demo version
This commit is contained in:
parent
fbb282a801
commit
672d6daa8e
125 changed files with 17918 additions and 1481 deletions
|
@ -0,0 +1,876 @@
|
|||
# distutils: language=c++
|
||||
# cython: embedsignature=True, language_level=3
|
||||
|
||||
###############################################################################/
|
||||
# Copyright (c) 2021 Nerian Vision GmbH
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
###############################################################################/
|
||||
|
||||
'''
|
||||
Python 3 wrapper for libvisiontransfer by Nerian Vision
|
||||
|
||||
This module is a wrapper for the libvisiontransfer library,
|
||||
used to control and acquire data from Nerian's line of stereo
|
||||
vision devices.
|
||||
|
||||
This documentation is largely autogenerated from the
|
||||
C++ library doxygen annotations:
|
||||
|
||||
Please note that in some instances, the actual functions have been
|
||||
adapted to be more Pythonic from their C++-specific calling conventions.
|
||||
In particular, the auto-generated documentation of parameter getter
|
||||
functions may indicate a number of arguments (C++ reference arguments),
|
||||
but they actually directly return tuples in this Python library.
|
||||
Refer to their Cython signature line (first line of their docstring)
|
||||
to see the true arguments you can use; the rest of the arguments in
|
||||
the C++ argument list is instead returned as a result tuple.
|
||||
|
||||
=============================================================================
|
||||
|
||||
Copyright (c) 2021 Nerian Vision GmbH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
'''
|
||||
|
||||
cimport visiontransfer_cpp as cpp
|
||||
|
||||
# Autogenerated parameter access in extra file
|
||||
include "visiontransfer/visiontransfer_parameters_autogen.pyx"
|
||||
|
||||
from libcpp.string cimport string
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp cimport bool
|
||||
from cython cimport view
|
||||
|
||||
cimport numpy as np
|
||||
import numpy as np
|
||||
np.import_array()
|
||||
|
||||
import enum
|
||||
import sys
|
||||
import time
|
||||
|
||||
class AutoMode(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceParameters::AutoMode")
|
||||
AUTO_EXPOSURE_AND_GAIN = 0
|
||||
AUTO_EXPOSURE_MANUAL_GAIN = 1
|
||||
MANUAL_EXPOSURE_AUTO_GAIN = 2
|
||||
MANUAL_EXPOSURE_MANUAL_GAIN = 3
|
||||
|
||||
class DeviceModel(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceParameters::DeviceModel")
|
||||
SCENESCAN = 0
|
||||
SCENESCAN_PRO = 1
|
||||
|
||||
class NetworkProtocol(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::NetworkProtocol")
|
||||
PROTOCOL_TCP = 0
|
||||
PROTOCOL_UDP = 1
|
||||
|
||||
class ProtocolType(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageProtocol::ProtocolType")
|
||||
PROTOCOL_TCP = 0
|
||||
PROTOCOL_UDP = 1
|
||||
|
||||
class ImageFormat(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::ImageFormat")
|
||||
FORMAT_8_BIT_MONO = 0
|
||||
FORMAT_8_BIT_RGB = 1
|
||||
FORMAT_12_BIT_MONO = 2
|
||||
|
||||
class ImageType(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::ImageType")
|
||||
IMAGE_UNDEFINED = 0
|
||||
IMAGE_LEFT = 1
|
||||
IMAGE_DISPARITY = 2
|
||||
IMAGE_RIGHT = 3
|
||||
|
||||
class OperationMode(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceParameters::OperationMode")
|
||||
PASS_THROUGH = 0
|
||||
RECTIFY = 1
|
||||
STEREO_MATCHING = 2
|
||||
|
||||
class TargetFrame(enum.IntEnum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceParameters::TargetFrame")
|
||||
LEFT_FRAME = 0
|
||||
RIGHT_FRAME = 1
|
||||
BOTH_FRAMES = 2
|
||||
|
||||
cdef class DeviceEnumeration:
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceEnumeration")
|
||||
|
||||
cdef cpp.DeviceEnumeration c_obj
|
||||
|
||||
def discover_devices(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceEnumeration::discoverDevices")
|
||||
device_infos = []
|
||||
cdef vector[cpp.DeviceInfo] devices = self.c_obj.discoverDevices()
|
||||
for device in devices:
|
||||
di = DeviceInfo()
|
||||
di.c_obj = device
|
||||
device_infos.append(di)
|
||||
return device_infos
|
||||
|
||||
cdef class DeviceInfo:
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo")
|
||||
cdef cpp.DeviceInfo c_obj
|
||||
|
||||
def get_ip_address(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::getIpAddress")
|
||||
cdef string s = self.c_obj.getIpAddress()
|
||||
return s.decode("utf-8")
|
||||
|
||||
def get_network_protocol(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::getNetworkProtocol")
|
||||
return NetworkProtocol(self.c_obj.getNetworkProtocol())
|
||||
|
||||
def get_firmware_version(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::getFirmwareVersion")
|
||||
cdef string s = self.c_obj.getFirmwareVersion()
|
||||
return s.decode("utf-8")
|
||||
|
||||
def get_model(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::getModel")
|
||||
return DeviceModel(self.c_obj.getModel())
|
||||
|
||||
def get_status(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::getStatus")
|
||||
ds = DeviceStatus()
|
||||
ds.c_obj = self.c_obj.getStatus()
|
||||
return ds
|
||||
|
||||
def is_compatible(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceInfo::isCompatible")
|
||||
return self.c_obj.isCompatible()
|
||||
|
||||
def __str__(self):
|
||||
cdef string s = self.c_obj.toString()
|
||||
return s.decode("utf-8")
|
||||
|
||||
__repr__ = __str__
|
||||
|
||||
|
||||
cdef class DeviceStatus:
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceStatus")
|
||||
cdef cpp.DeviceStatus c_obj
|
||||
|
||||
def is_valid(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceStatus::isValid")
|
||||
return self.c_obj.isValid()
|
||||
|
||||
def get_last_fps(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceStatus::getLastFps")
|
||||
return self.c_obj.getLastFps()
|
||||
|
||||
def get_jumbo_mtu(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceStatus::getJumboMtu")
|
||||
return self.c_obj.getJumboMtu()
|
||||
|
||||
def get_jumbo_frames_enabled(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceStatus::getJumboFramesEnabled")
|
||||
# return as bool here (still uint in API)
|
||||
return self.c_obj.getJumboFramesEnabled() != 0
|
||||
|
||||
def get_current_capture_source(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::DeviceStatus::getCurrentCaptureSource")
|
||||
cdef string s = self.c_obj.getCurrentCaptureSource()
|
||||
return s.decode("utf-8")
|
||||
|
||||
def create_image_set_from_reduced_data(width, height, nimg, indices, strides, formats, data, qmat, seqnum, subpix, expos, disprange, times, lastsync):
|
||||
'''Only for internal use (shim for unpickling / copy).'''
|
||||
imset = ImageSet()
|
||||
imset.set_width(width)
|
||||
imset.set_height(height)
|
||||
imset.set_number_of_images(nimg)
|
||||
for i, what in enumerate([ImageType.IMAGE_LEFT, ImageType.IMAGE_DISPARITY, ImageType.IMAGE_RIGHT]):
|
||||
imset.set_index_of(what, indices[i])
|
||||
for i in range(nimg):
|
||||
imset.set_row_stride(i, strides[i])
|
||||
imset.set_pixel_format(i, formats[i])
|
||||
imset.set_pixel_data(i, data[i])
|
||||
imset.set_qmatrix(qmat)
|
||||
imset.set_sequence_number(seqnum)
|
||||
imset.set_subpixel_factor(subpix)
|
||||
imset.set_exposure_time(expos)
|
||||
a, b = disprange
|
||||
imset.set_disparity_range(a, b)
|
||||
a, b = times
|
||||
imset.set_timestamp(a, b)
|
||||
a, b = lastsync
|
||||
imset.set_last_sync_pulse(a, b)
|
||||
return imset
|
||||
|
||||
cdef class ImageSet:
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet")
|
||||
cdef cpp.ImageSet c_obj
|
||||
|
||||
cdef np.ndarray _numpy_q
|
||||
cdef list _numpy_pixels
|
||||
cdef bool _touched_internally
|
||||
|
||||
def __cinit__(self):
|
||||
# These members are just here to keep alive the refcounted
|
||||
# data references for ImageSets created on the Python side
|
||||
# (e.g. unpickled data) -- bear in mind the C++ API purely
|
||||
# operates on unmanaged raw data pointers into numpy arrays.
|
||||
self._numpy_q = None
|
||||
self._numpy_pixels = [None]*3 # MAX_SUPPORTED_IMAGES
|
||||
# Successfully setting pixel data from Python flags this
|
||||
# object, whitelisting later overwriting (which is prevented
|
||||
# a priori for all C++-/ImageTransfer-managed objects).
|
||||
self._touched_internally = False
|
||||
|
||||
def __reduce__(self):
|
||||
nimg = self.get_number_of_images()
|
||||
return (create_image_set_from_reduced_data, (
|
||||
self.get_width(),
|
||||
self.get_height(),
|
||||
nimg,
|
||||
[self.get_index_of(i) for i in [ImageType.IMAGE_LEFT, ImageType.IMAGE_DISPARITY, ImageType.IMAGE_RIGHT]],
|
||||
[self.get_row_stride(i) for i in range(nimg)],
|
||||
[self.get_pixel_format(i) for i in range(nimg)],
|
||||
[self.get_pixel_data_raw(i) for i in range(nimg)],
|
||||
self.get_qmatrix(),
|
||||
self.get_sequence_number(),
|
||||
self.get_subpixel_factor(),
|
||||
self.get_exposure_time(),
|
||||
self.get_disparity_range(),
|
||||
self.get_timestamp(),
|
||||
self.get_last_sync_pulse(),
|
||||
))
|
||||
|
||||
def __str__(self):
|
||||
w = self.get_width()
|
||||
h = self.get_height()
|
||||
return f"ImageSet({w}, {h})"
|
||||
|
||||
__repr__ = __str__
|
||||
|
||||
def copy(self):
|
||||
'''
|
||||
Create a full copy of the ImageSet. All its data is managed by Python (i.e.
|
||||
no deallocation attempts by the C++ API will ever take place on this clone).
|
||||
'''
|
||||
cloned = ImageSet()
|
||||
nimg = self.get_number_of_images()
|
||||
cloned.set_height(self.get_height())
|
||||
cloned.set_width(self.get_width())
|
||||
cloned.set_number_of_images(nimg)
|
||||
for i in [ImageType.IMAGE_LEFT, ImageType.IMAGE_DISPARITY, ImageType.IMAGE_RIGHT]:
|
||||
cloned.set_index_of(i, self.get_index_of(i))
|
||||
for i in range(nimg):
|
||||
cloned.set_row_stride(i, self.get_row_stride(i))
|
||||
cloned.set_pixel_format(i, self.get_pixel_format(i))
|
||||
sz = cloned.get_height() * cloned.get_row_stride(i)
|
||||
cloned.set_pixel_data(i, self.get_pixel_data_raw(i).copy())
|
||||
# this also sets _touched_internally -> data is replaceable
|
||||
cloned.set_qmatrix(self.get_qmatrix())
|
||||
cloned.set_sequence_number(self.get_sequence_number())
|
||||
cloned.set_subpixel_factor(self.get_subpixel_factor())
|
||||
cloned.set_exposure_time(self.get_exposure_time())
|
||||
a, b = self.get_disparity_range()
|
||||
cloned.set_disparity_range(a, b)
|
||||
a, b = self.get_timestamp()
|
||||
cloned.set_timestamp(a, b)
|
||||
a, b = self.get_last_sync_pulse()
|
||||
cloned.set_last_sync_pulse(a, b)
|
||||
return cloned
|
||||
|
||||
def get_width(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getWidth")
|
||||
return self.c_obj.getWidth()
|
||||
|
||||
def get_height(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getHeight")
|
||||
return self.c_obj.getHeight()
|
||||
|
||||
def get_row_stride(self, image_number):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getRowStride")
|
||||
return self.c_obj.getRowStride(image_number)
|
||||
|
||||
def get_pixel_format(self, what):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getPixelFormat")
|
||||
image_number = self.get_index_of(what, True) if isinstance(what, ImageType) else int(what)
|
||||
return ImageFormat(self.c_obj.getPixelFormat(<int> image_number))
|
||||
|
||||
def get_pixel_data_raw(self, what):
|
||||
'''Return a flat uint8 view of the image data of the specified channel (primarily for internal use).'''
|
||||
image_number = self.get_index_of(what, True) if isinstance(what, ImageType) else int(what)
|
||||
cdef int rowstride = self.c_obj.getRowStride(image_number)
|
||||
cdef int h = self.c_obj.getHeight()
|
||||
cdef int size = rowstride * h
|
||||
np_array = self._pixel_data_as_char_array(image_number, size)
|
||||
return np_array
|
||||
|
||||
def get_pixel_data(self, what, force8bit=False, do_copy=True):
|
||||
'''
|
||||
Obtain a numpy array containing the image data for a channel.
|
||||
Args:
|
||||
what: The ImageType or image index to retrieve.
|
||||
force8bit: optional flag, causes rescaling to 0..255 in case of 12-bit images (dividing by 16).
|
||||
do_copy: copy the final array view (default True; primarily for internal use, disable with caution)
|
||||
|
||||
Returns:
|
||||
The image data as a copied numpy array; two-dimensional for monochrome images, three-dimensional for RGB.
|
||||
'''
|
||||
|
||||
image_number = self.get_index_of(what, True) if isinstance(what, ImageType) else int(what)
|
||||
|
||||
cdef int rowstride = self.c_obj.getRowStride(image_number)
|
||||
cdef int w = self.c_obj.getWidth()
|
||||
cdef int h = self.c_obj.getHeight()
|
||||
cdef int size
|
||||
|
||||
fmt = self.get_pixel_format(image_number)
|
||||
if fmt == ImageFormat.FORMAT_12_BIT_MONO:
|
||||
size = (rowstride * h) // 2
|
||||
np_array = self._pixel_data_as_short_array(image_number, size)
|
||||
np_array = np_array.reshape(h, rowstride//2)
|
||||
np_array = np_array[:, :w]
|
||||
if force8bit:
|
||||
return (np_array // 16).astype(np.uint8) # implicit copy
|
||||
else:
|
||||
return np_array.copy() if do_copy else np_array
|
||||
elif fmt == ImageFormat.FORMAT_8_BIT_RGB:
|
||||
size = rowstride * h
|
||||
np_array = self._pixel_data_as_char_array(image_number, size)
|
||||
np_array = np_array.reshape(h, rowstride//3, 3)
|
||||
np_array = np_array[:, :w, :]
|
||||
return np_array.copy() if do_copy else np_array
|
||||
elif fmt == ImageFormat.FORMAT_8_BIT_MONO:
|
||||
size = rowstride * h
|
||||
np_array = self._pixel_data_as_char_array(image_number, size)
|
||||
np_array = np_array.reshape(h, rowstride)
|
||||
np_array = np_array[:, :w]
|
||||
return np_array.copy() if do_copy else np_array
|
||||
|
||||
cdef _pixel_data_as_short_array(self, int image_number, int size):
|
||||
cdef unsigned char* pointer = self.c_obj.getPixelData(image_number)
|
||||
cdef np.uint16_t* short_prt = <np.uint16_t *> pointer
|
||||
cdef np.uint16_t[:] myview = <np.uint16_t[:size]> short_prt
|
||||
return np.asarray(myview)
|
||||
|
||||
cdef _pixel_data_as_char_array(self, int image_number, int size):
|
||||
cdef unsigned char* pointer = self.c_obj.getPixelData(image_number)
|
||||
cdef np.uint8_t[:] char_view = <np.uint8_t[:size]> pointer
|
||||
return np.asarray(char_view)
|
||||
|
||||
def get_qmatrix(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getQMatrix")
|
||||
cdef view.array ar = view.array(shape=(16, ), itemsize=sizeof(float), format="f", mode="c", allocate_buffer=False)
|
||||
cdef const float* pointer = self.c_obj.getQMatrix()
|
||||
ar.data = <char*> pointer
|
||||
np_array = np.asarray(ar)
|
||||
np_array = np_array.reshape(4, 4)
|
||||
return np_array
|
||||
|
||||
def get_sequence_number(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getSequenceNumber")
|
||||
return self.c_obj.getSequenceNumber()
|
||||
|
||||
def get_timestamp(self):
|
||||
'''
|
||||
Returns the time at which this image set has been captured.
|
||||
|
||||
Returns:
|
||||
sec, usec: A tuple representing the time stamp: the integer seconds, and the
|
||||
fractional seconds part in microseconds.
|
||||
'''
|
||||
cdef int sec = 0
|
||||
cdef int usec = 0
|
||||
self.c_obj.getTimestamp(sec, usec)
|
||||
return sec, usec
|
||||
|
||||
def get_disparity_range(self):
|
||||
'''
|
||||
Gets the value range for the disparity map contained in this
|
||||
image set. If the image set does not contain any disparity data
|
||||
then the disparity range is undefined.
|
||||
|
||||
Returns:
|
||||
minimum, maximum: The minimum and maximum disparity in the image set.
|
||||
'''
|
||||
cdef int minimum = 0
|
||||
cdef int maximum = 0
|
||||
self.c_obj.getDisparityRange(minimum, maximum)
|
||||
return minimum, maximum
|
||||
|
||||
def get_subpixel_factor(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getSubpixelFactor")
|
||||
return self.c_obj.getSubpixelFactor()
|
||||
|
||||
def write_pgm_file(self, image_number, filename):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::writePgmFile")
|
||||
self.c_obj.writePgmFile(image_number, filename.encode())
|
||||
|
||||
def is_image_disparity_pair(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::isImageDisparityPair")
|
||||
return self.c_obj.isImageDisparityPair()
|
||||
|
||||
def get_bytes_per_pixel(self, what):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getBytesPerPixel")
|
||||
image_number = self.get_index_of(what, True) if isinstance(what, ImageType) else int(what)
|
||||
return self.c_obj.getBytesPerPixel(<int> image_number)
|
||||
|
||||
def get_number_of_images(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getNumberOfImages")
|
||||
return self.c_obj.getNumberOfImages()
|
||||
|
||||
def get_index_of(self, what, throw_if_not_found=False):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getIndexOf")
|
||||
return self.c_obj.getIndexOf(what, throw_if_not_found)
|
||||
|
||||
def has_image_type(self, what):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::hasImageType")
|
||||
return self.c_obj.hasImageType(what)
|
||||
|
||||
def get_exposure_time(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::getExposureTime")
|
||||
return self.c_obj.getExposureTime()
|
||||
|
||||
def get_last_sync_pulse(self):
|
||||
'''
|
||||
Gets the timestamp of the last received sync pulse.
|
||||
|
||||
Returns:
|
||||
sec, usec: A tuple representing the time stamp: the integer seconds, and the
|
||||
fractional seconds part in microseconds.
|
||||
'''
|
||||
cdef int sec = 0
|
||||
cdef int usec = 0
|
||||
self.c_obj.getLastSyncPulse(sec, usec)
|
||||
return sec, usec
|
||||
|
||||
def set_width(self, width):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setWidth")
|
||||
self.c_obj.setWidth(width)
|
||||
|
||||
def set_height(self, height):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setHeight")
|
||||
self.c_obj.setHeight(height)
|
||||
|
||||
def set_row_stride(self, image_number, row_stride):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setRowStride")
|
||||
self.c_obj.setRowStride(image_number, row_stride)
|
||||
|
||||
def set_pixel_format(self, image_number, image_format):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setPixelFormat")
|
||||
self.c_obj.setPixelFormat(image_number, image_format)
|
||||
|
||||
def set_pixel_data(self, image_number, np.ndarray[np.uint8_t, ndim=1, mode="c"] pixel_data):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setPixelData")
|
||||
cdef unsigned char* oldptr = self.c_obj.getPixelData(image_number)
|
||||
if oldptr != NULL and not self._touched_internally:
|
||||
# This is the only kind of data access we actively prevent here.
|
||||
# The C++ API (ImageTransfer) would have no way of freeing its own
|
||||
# buffers, and would try to free the numpy array data instead!
|
||||
# The double check is done because it is OK to replace one numpy
|
||||
# array with a different one (not really sensible, but valid).
|
||||
raise RuntimeError('Refused to set pixel data: pixel data is managed by the C++ API. Please use copy() or start from an empty ImageSet.')
|
||||
self.c_obj.setPixelData(image_number, &pixel_data[0]) # raw pointer is stored (will throw here on invalid index)
|
||||
self._numpy_pixels[image_number] = pixel_data # store locally for refcount
|
||||
self._touched_internally = True # object is whitelisted for overwriting data
|
||||
|
||||
def set_qmatrix(self, np.ndarray[float, ndim=2, mode="c"] q):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setQMatrix")
|
||||
self.c_obj.setQMatrix(&q[0, 0]) # a raw pointer is passed and stored
|
||||
self._numpy_q = q # but a reference is stored here to hold a refcount
|
||||
|
||||
def set_sequence_number(self, num):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setSequenceNumber")
|
||||
self.c_obj.setSequenceNumber(num)
|
||||
|
||||
def set_timestamp(self, sec, usec):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setTimestamp")
|
||||
self.c_obj.setTimestamp(sec, usec)
|
||||
|
||||
def set_disparity_range(self, minimum, maximum):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setDisparityRange")
|
||||
self.c_obj.setDisparityRange(minimum, maximum)
|
||||
|
||||
def set_subpixel_factor(self, subpixel_factor):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setSubpixelFactor")
|
||||
self.c_obj.setSubpixelFactor(subpixel_factor)
|
||||
|
||||
def set_number_of_images(self, number):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setNumberOfImages")
|
||||
cdef unsigned char* oldptr = self.c_obj.getPixelData(0)
|
||||
# Changing the number of images with data present could mess up
|
||||
# memory management (e.g. by allowing to add numpy data to new
|
||||
# channels of C++-managed objects, or preventing necessary frees).
|
||||
# Therefore, we allow setting this number only in ImageSets that
|
||||
# have only been filled from the Python side.
|
||||
if oldptr != NULL and not self._touched_internally:
|
||||
raise RuntimeError('Refused to change number of images: pixel data is managed by the C++ API. Please use copy() or start from an empty ImageSet.')
|
||||
self.c_obj.setNumberOfImages(number)
|
||||
|
||||
def set_index_of(self, what, idx):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setIndexOf")
|
||||
self.c_obj.setIndexOf(what, idx)
|
||||
|
||||
def set_exposure_time(self, time_microsec):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setExposureTime")
|
||||
self.c_obj.setExposureTime(time_microsec)
|
||||
|
||||
def set_last_sync_pulse(self, sec, usec):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageSet::setLastSyncPulse")
|
||||
return self.c_obj.setLastSyncPulse(sec, usec)
|
||||
|
||||
|
||||
cdef class ImageTransfer:
|
||||
'''
|
||||
Class for synchronous transfer of image sets.
|
||||
|
||||
This class opens a network socket for delivering or receiving image sets. All
|
||||
operations are performed synchronously, which means that they might block.
|
||||
The class encapsulates ImageProtocol.
|
||||
|
||||
This class is thread safe for as long as sending and receiving data
|
||||
each has its dedicated thread.
|
||||
|
||||
Note for Python version: for best performance, the use of AsyncTransfer
|
||||
is recommended for all regular desktop systems.
|
||||
'''
|
||||
cdef cpp.ImageTransfer* c_obj
|
||||
|
||||
def __cinit__(self, DeviceInfo device, int buffer_size=1048576, int max_udp_packet_size=1472):
|
||||
self.c_obj = new cpp.ImageTransfer(device.c_obj, buffer_size, max_udp_packet_size)
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.c_obj
|
||||
|
||||
def is_connected(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageTransfer::isConnected")
|
||||
return self.c_obj.isConnected()
|
||||
|
||||
def disconnect(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageTransfer::disconnect")
|
||||
self.c_obj.disconnect()
|
||||
|
||||
def get_remote_address(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageTransfer::getRemoteAddress")
|
||||
cdef string s = self.c_obj.getRemoteAddress()
|
||||
return s.decode("utf-8")
|
||||
|
||||
def receive_image_pair(self):
|
||||
'''DEPRECATED: Use receive_image_set() instead.'''
|
||||
return self.receive_image_set()
|
||||
|
||||
def receive_image_set(self):
|
||||
'''
|
||||
Waits for and receives a new image set.
|
||||
|
||||
Returns:
|
||||
Returns an ImageSet a new image set has been received. Otherwise
|
||||
None.
|
||||
|
||||
The received image set is only valid until the next call of receive_image_set.
|
||||
The method will not block indefinitely, but return after a short timeout.
|
||||
|
||||
You can use receive() as a Python library convenience wrapper
|
||||
for more efficient repolling with custom delay and number of attempts.
|
||||
'''
|
||||
imp = ImageSet()
|
||||
ret = self.c_obj.receiveImageSet(imp.c_obj)
|
||||
return imp if ret else None
|
||||
|
||||
def receive(self, timeout=-1, poll_delay=0.001):
|
||||
'''
|
||||
Python: polling wrapper for receive_image_set.
|
||||
|
||||
Args:
|
||||
timeout: The timeout in seconds before returning None unless an
|
||||
image arrives. A non-positive timeout means to wait forever.
|
||||
poll_delay: The sleep delay to enforce after each polling
|
||||
attempt.
|
||||
|
||||
Returns:
|
||||
An ImageSet if an image set has been received before the timeout.
|
||||
None otherwise.
|
||||
|
||||
On desktop systems, use AsyncTransfer instead for best performance.
|
||||
'''
|
||||
imp = ImageSet()
|
||||
t0 = time.time()
|
||||
while timeout <= 0 or (time.time() - t0) < timeout:
|
||||
ret = self.c_obj.receiveImageSet(imp.c_obj)
|
||||
if ret: return imp
|
||||
time.sleep(poll_delay)
|
||||
return None
|
||||
|
||||
def get_num_dropped_frames(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::ImageTransfer::getNumDroppedFrames")
|
||||
return self.c_obj.getNumDroppedFrames()
|
||||
|
||||
cdef class AsyncTransfer:
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::AsyncTransfer")
|
||||
cdef cpp.AsyncTransfer* c_obj
|
||||
|
||||
def __cinit__(self, DeviceInfo device, int buffer_size=1048576, int max_udp_packet_size=1472):
|
||||
self.c_obj = new cpp.AsyncTransfer(device.c_obj, buffer_size, max_udp_packet_size)
|
||||
|
||||
def __dealloc__(self):
|
||||
del self.c_obj
|
||||
|
||||
def is_connected(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::AsyncTransfer::isConnected")
|
||||
return self.c_obj.isConnected()
|
||||
|
||||
def disconnect(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::AsyncTransfer::disconnect")
|
||||
self.c_obj.disconnect()
|
||||
|
||||
def get_remote_address(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::AsyncTransfer::getRemoteAddress")
|
||||
cdef string s = self.c_obj.getRemoteAddress()
|
||||
return s.decode("utf-8")
|
||||
|
||||
def collect_received_image_pair(self, timeout=-1):
|
||||
'''DEPRECATED: Use collect_received_image_set() instead.'''
|
||||
return self.collect_received_image_set(timeout)
|
||||
|
||||
def collect_received_image_set(self, timeout=-1):
|
||||
'''
|
||||
Collects the asynchronously received image.
|
||||
|
||||
Args:
|
||||
timeout: The maximum time in seconds for which to wait if no
|
||||
image set has been received yet.
|
||||
|
||||
Returns:
|
||||
An ImageSet if an image set has been received before the timeout.
|
||||
|
||||
If no image set has been received, this method might block or return None.
|
||||
Otherwise the returned image set is valid until the next call.
|
||||
|
||||
If timeout is set to a value < 0, the function will block indefinitely.
|
||||
If timeout = 0, the function will return immediately, and if timeout is > 0 then
|
||||
the function will block for the given amount of time in seconds. The received
|
||||
image set is only valid until the next call of this function.
|
||||
'''
|
||||
imp = ImageSet()
|
||||
ret = self.c_obj.collectReceivedImageSet(imp.c_obj, timeout)
|
||||
return imp if ret else None
|
||||
|
||||
def get_num_dropped_frames(self):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::AsyncTransfer::getNumDroppedFrames")
|
||||
return self.c_obj.getNumDroppedFrames()
|
||||
|
||||
cdef class Reconstruct3D:
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::Reconstruct3D")
|
||||
cdef cpp.Reconstruct3D c_obj
|
||||
|
||||
def create_point_map_from_disparity_data(self, disp_map_data, width, height, row_stride, q, min_disparity=1, subpixel_factor=16, max_z=0, max_disparity=0xFFF):
|
||||
'''
|
||||
Reconstructs the 3D location of each pixel in the given disparity map,
|
||||
with custom parameters.
|
||||
|
||||
Args:
|
||||
disp_map_data: Data of the disparity map (unsigned short array). The
|
||||
disparity map is assumed to have a N-bit subpixel resolution.
|
||||
This means that each value needs to be divided by the subpixel factor
|
||||
to receive the true disparity.
|
||||
width, height: Disparity map dimensions
|
||||
row_stride: Row stride (i.e. distance between two rows in bytes)
|
||||
of the disparity map.
|
||||
q: Disparity-to-depth mapping matrix of size 4x4. The matrix is
|
||||
stored in a row-wise alignment. Obtain this matrix from your
|
||||
camera calibration data.
|
||||
minDisparity: The minimum disparity, again with N-bit subpixel
|
||||
resolution. Lower disparities will be clamped to this value
|
||||
before computing the 3D location (default 1).
|
||||
subpixel_factor: Subpixel division factor for disparity value
|
||||
(default 16)
|
||||
max_z: (Python specific) Filter the numpy array to only return
|
||||
points closer than specified value. A non-positive value means
|
||||
no filtering (default).
|
||||
max_disparity: The maximum value that occurs in the disparity map. Any value
|
||||
greater or equal will be marked as invalid.
|
||||
Returns:
|
||||
A numpy array of size [:,3] containing the 3D points corresponding to the disparity map.
|
||||
|
||||
Please refer to the C++ API docs for further details.
|
||||
'''
|
||||
cdef int size = width * height * 4
|
||||
cdef unsigned short[:, ::1] disp_map_arr = disp_map_data
|
||||
cdef float[:, ::1] q_arr = q.astype(np.float32)
|
||||
cdef float* point_map_data = self.c_obj.createPointMap(&disp_map_arr[0, 0], width, height, row_stride, &q_arr[0, 0], min_disparity, subpixel_factor, max_disparity)
|
||||
|
||||
cdef view.array arr = view.array(shape=(size,), itemsize=sizeof(float), format="f", mode="c", allocate_buffer=False)
|
||||
arr.data = <char*> point_map_data
|
||||
|
||||
np_array = np.asarray(arr)
|
||||
np_array = np_array.reshape(height * width, 4)
|
||||
np_array = np_array[:, :3]
|
||||
|
||||
if max_z > 0:
|
||||
np_array = np_array[np_array[:, 2] < max_z]
|
||||
|
||||
return np_array
|
||||
|
||||
def create_point_map(self, ImageSet image_set, min_disparity=1, max_z=0):
|
||||
'''
|
||||
Reconstructs the 3D location of each pixel using the disparity map
|
||||
and metadata of the given image set.
|
||||
|
||||
Args:
|
||||
image_set: Image set containing the disparity map.
|
||||
min_disparity: The minimum disparity with 4-bit subpixel resolution.
|
||||
max_z: (Python specific) Filter the numpy array to only return
|
||||
points closer than specified value. A non-positive value means
|
||||
no filtering (default).
|
||||
|
||||
Returns:
|
||||
A numpy array of size [:,3] containing the 3D points corresponding to the disparity map.
|
||||
|
||||
Please refer to the C++ API docs for further details.
|
||||
'''
|
||||
cdef int w = image_set.c_obj.getWidth()
|
||||
cdef int h = image_set.c_obj.getHeight()
|
||||
cdef int size = w * h * 4
|
||||
cdef float* point_map_data = self.c_obj.createPointMap(image_set.c_obj, min_disparity)
|
||||
|
||||
cdef view.array arr = view.array(shape=(size,), itemsize=sizeof(float), format="f", mode="c", allocate_buffer=False)
|
||||
arr.data = <char*> point_map_data
|
||||
|
||||
np_array = np.asarray(arr)
|
||||
np_array = np_array.reshape(h * w, 4)
|
||||
np_array = np_array[:, :3]
|
||||
|
||||
if max_z > 0:
|
||||
np_array = np_array[np_array[:, 2] < max_z]
|
||||
|
||||
return np_array
|
||||
|
||||
def create_point_map_and_color_map(self, ImageSet image_set, min_disparity=1, max_z=0):
|
||||
'''
|
||||
Reconstructs the 3D location of each pixel using the disparity map
|
||||
and metadata of the given image set, alongside their colors.
|
||||
|
||||
Args:
|
||||
image_set: Image set containing the disparity map.
|
||||
min_disparity: The minimum disparity with 4-bit subpixel resolution.
|
||||
max_z: (Python specific) Filter the numpy array to only return
|
||||
points closer than specified value. A non-positive value means
|
||||
no filtering (default).
|
||||
|
||||
Returns:
|
||||
Two numpy arrays of identical size [:,3], the first containing the 3D points corresponding
|
||||
to the disparity map, and the second one their colors as float RGB triplets (or None if
|
||||
the ImageSet is disparity-only).
|
||||
'''
|
||||
cdef int w = image_set.c_obj.getWidth()
|
||||
cdef int h = image_set.c_obj.getHeight()
|
||||
cdef int size = w * h * 4
|
||||
cdef float* point_map_data = self.c_obj.createPointMap(image_set.c_obj, min_disparity)
|
||||
|
||||
cdef view.array arr = view.array(shape=(size,), itemsize=sizeof(float), format="f", mode="c", allocate_buffer=False)
|
||||
arr.data = <char*> point_map_data
|
||||
|
||||
coords = np.asarray(arr)
|
||||
coords = coords.reshape(h * w, 4)
|
||||
coords = coords[:, :3]
|
||||
|
||||
pix = None
|
||||
if image_set.has_image_type(ImageType.IMAGE_LEFT):
|
||||
pix = image_set.get_pixel_data(ImageType.IMAGE_LEFT, force8bit=True, do_copy=False)
|
||||
if len(pix.shape)==2: pix = np.stack([pix]*3, 2) # Expand grayscale to rgb triplets
|
||||
pix = pix.reshape((-1, 3)).astype(np.float64) / 255.0
|
||||
|
||||
if max_z > 0:
|
||||
if pix is not None:
|
||||
pix = pix[coords[:, 2] < max_z]
|
||||
coords = coords[coords[:, 2] < max_z]
|
||||
|
||||
return coords, pix
|
||||
|
||||
def create_open3d_pointcloud(self, ImageSet image_set, min_disparity=1, max_z=0):
|
||||
'''
|
||||
Convenience wrapper to directly return an Open3D point cloud for an image set.
|
||||
|
||||
Args:
|
||||
image_set: Image set containing the disparity map.
|
||||
min_disparity: The minimum disparity with 4-bit subpixel resolution.
|
||||
max_z: (Python specific) Filter the point cloud data to only return
|
||||
points closer than specified value. A non-positive value means
|
||||
no filtering (default).
|
||||
|
||||
Returns:
|
||||
An open3d.geometry.PointCloud for the (filtered) coordinates from the ImageSet.
|
||||
Contains color information unless the ImageSet was disparity-only.
|
||||
'''
|
||||
import open3d
|
||||
pointmap, colors = self.create_point_map_and_color_map(image_set, min_disparity=min_disparity, max_z=max_z)
|
||||
pcd = open3d.geometry.PointCloud(open3d.utility.Vector3dVector(pointmap))
|
||||
if colors is not None:
|
||||
pcd.colors = open3d.utility.Vector3dVector(colors)
|
||||
return pcd
|
||||
|
||||
def create_open3d_rgbd_image(self, ImageSet image_set, min_disparity=1, depth_trunc=3.0, depth_scale=1.0):
|
||||
'''
|
||||
Convenience wrapper to directly return an Open3D RGBD image for an ImageSet.
|
||||
Raises a RuntimeError when called with a disparity-only image set.
|
||||
|
||||
Args:
|
||||
image_set: Image set containing the disparity map.
|
||||
min_disparity: The minimum disparity with 4-bit subpixel resolution.
|
||||
depth_trunc: (Open3D argument, relayed) Filter the depth channel to
|
||||
zero-clamp points more distant than the specified value (default 3.0).
|
||||
|
||||
Returns:
|
||||
An open3d.geometry.RGBDImage for the image set.
|
||||
'''
|
||||
import open3d
|
||||
|
||||
if not image_set.has_image_type(ImageType.IMAGE_LEFT):
|
||||
raise RuntimeError('Cannot create an RGBD image - no left image data in ImageSet')
|
||||
|
||||
cdef int w = image_set.c_obj.getWidth()
|
||||
cdef int h = image_set.c_obj.getHeight()
|
||||
cdef float* z_data = self.c_obj.createZMap(image_set.c_obj, minDisparity=min_disparity, maxDisparity=0xFFF)
|
||||
cdef view.array arr = view.array(shape=(h, w,), itemsize=sizeof(float), format="f", mode="c", allocate_buffer=False)
|
||||
arr.data = <char*> z_data
|
||||
depth = np.asarray(arr).astype(np.float32)
|
||||
|
||||
color = image_set.get_pixel_data(ImageType.IMAGE_LEFT, force8bit=True)
|
||||
|
||||
img = open3d.geometry.RGBDImage.create_from_color_and_depth(
|
||||
open3d.cpu.pybind.geometry.Image(color),
|
||||
open3d.cpu.pybind.geometry.Image(depth),
|
||||
depth_scale=depth_scale, depth_trunc=depth_trunc)
|
||||
return img
|
||||
|
||||
def project_single_point(self, point_x, point_y, disparity, q, subpix_factor):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::Reconstruct3D::projectSinglePoint", "PYTHON NOTE: Returns a tuple (pointX, pointY, pointZ). Please ignore those C++ reference arguments.")
|
||||
cdef float proj_x = 0
|
||||
cdef float proj_y = 0
|
||||
cdef float proj_z = 0
|
||||
cdef float[:, ::1] q_arr = q.astype(np.float32)
|
||||
self.c_obj.projectSinglePoint(point_x, point_y, disparity, &q_arr[0, 0], proj_x, proj_y, proj_z, subpix_factor)
|
||||
return proj_x, proj_y, proj_z
|
||||
|
||||
|
||||
def write_ply_file(self, filename, ImageSet image_set, double max_z=sys.float_info.max, bool binary=False):
|
||||
_SUBSTITUTE_DOCSTRING_FOR_("visiontransfer::Reconstruct3D::writePlyFile")
|
||||
self.c_obj.writePlyFile(filename.encode(), image_set.c_obj, max_z, binary)
|
||||
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
###############################################################################/
|
||||
# Copyright (c) 2021 Nerian Vision GmbH
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
###############################################################################/
|
||||
|
||||
from libcpp.vector cimport vector
|
||||
from libcpp.string cimport string
|
||||
from libcpp cimport bool
|
||||
|
||||
cdef extern from "visiontransfer/deviceinfo.h" namespace "visiontransfer::DeviceInfo::DeviceModel":
|
||||
cdef enum DeviceModel "visiontransfer::DeviceInfo::DeviceModel":
|
||||
SCENESCAN
|
||||
SCENESCAN_PRO
|
||||
|
||||
cdef extern from "visiontransfer/deviceinfo.h" namespace "visiontransfer::DeviceInfo::NetworkProtocol":
|
||||
cdef enum NetworkProtocol "visiontransfer::DeviceInfo::NetworkProtocol":
|
||||
PROTOCOL_TCP
|
||||
PROTOCOL_UDP
|
||||
|
||||
cdef extern from "visiontransfer/imageprotocol.h" namespace "visiontransfer::ImageProtocol::ProtocolType":
|
||||
cdef enum ProtocolType "visiontransfer::ImageProtocol::ProtocolType":
|
||||
PROTOCOL_TCP
|
||||
PROTOCOL_UDP
|
||||
|
||||
cdef extern from "visiontransfer/imageset.h" namespace "visiontransfer::ImageSet::ImageFormat":
|
||||
cdef enum ImageFormat "visiontransfer::ImageSet::ImageFormat":
|
||||
FORMAT_8_BIT_MONO
|
||||
FORMAT_8_BIT_RGB
|
||||
FORMAT_12_BIT_MONO
|
||||
|
||||
cdef extern from "visiontransfer/imageset.h" namespace "visiontransfer::ImageSet::ImageType":
|
||||
cdef enum ImageType "visiontransfer::ImageSet::ImageType":
|
||||
IMAGE_UNDEFINED
|
||||
IMAGE_LEFT
|
||||
IMAGE_DISPARITY
|
||||
IMAGE_RIGHT
|
||||
|
||||
cdef extern from "visiontransfer/deviceparameters.h" namespace "visiontransfer::DeviceParameters::AutoMode":
|
||||
cdef enum AutoMode "visiontransfer::DeviceParameters::AutoMode":
|
||||
AUTO_EXPOSURE_AND_GAIN
|
||||
AUTO_EXPOSURE_MANUAL_GAIN
|
||||
MANUAL_EXPOSURE_AUTO_GAIN
|
||||
MANUAL_EXPOSURE_MANUAL_GAIN
|
||||
|
||||
cdef extern from "visiontransfer/deviceparameters.h" namespace "visiontransfer::DeviceParameters::OperationMode":
|
||||
cdef enum OperationMode "visiontransfer::DeviceParameters::OperationMode":
|
||||
PASS_THROUGH
|
||||
RECTIFY
|
||||
STEREO_MATCHING
|
||||
|
||||
cdef extern from "visiontransfer/deviceparameters.h" namespace "visiontransfer::DeviceParameters::TargetFrame":
|
||||
cdef enum TargetFrame "visiontransfer::DeviceParameters::TargetFrame":
|
||||
LEFT_FRAME
|
||||
RIGHT_FRAME
|
||||
BOTH_FRAMES
|
||||
|
||||
cdef extern from "visiontransfer/deviceinfo.h" namespace "visiontransfer":
|
||||
cdef cppclass DeviceStatus:
|
||||
DeviceStatus() except +
|
||||
bool isValid() except +
|
||||
double getLastFps() except +
|
||||
unsigned int getJumboMtu() except +
|
||||
unsigned int getJumboFramesEnabled() except +
|
||||
string getCurrentCaptureSource() except +
|
||||
|
||||
cdef extern from "visiontransfer/deviceinfo.h" namespace "visiontransfer":
|
||||
cdef cppclass DeviceInfo:
|
||||
DeviceInfo() except +
|
||||
string getIpAddress() except +
|
||||
NetworkProtocol getNetworkProtocol() except +
|
||||
string getFirmwareVersion() except +
|
||||
DeviceModel getModel() except +
|
||||
DeviceStatus getStatus() except +
|
||||
bool isCompatible() except +
|
||||
string toString() except +
|
||||
|
||||
cdef extern from "visiontransfer/deviceenumeration.h" namespace "visiontransfer":
|
||||
cdef cppclass DeviceEnumeration:
|
||||
DeviceEnumeration() except +
|
||||
vector[DeviceInfo] discoverDevices() except +
|
||||
|
||||
cdef extern from "visiontransfer/imageset.h" namespace "visiontransfer":
|
||||
cdef cppclass ImageSet:
|
||||
ImageSet() except +
|
||||
int getWidth() except +
|
||||
int getHeight() except +
|
||||
int getRowStride(int imageNumber) except +
|
||||
ImageFormat getPixelFormat(int imageNumber) except +
|
||||
ImageFormat getPixelFormat(ImageType what) except +
|
||||
unsigned char* getPixelData(int imageNumber) except +
|
||||
const float* getQMatrix() except +
|
||||
int getSequenceNumber() except +
|
||||
void getTimestamp(int& seconds, int& microsec) except +
|
||||
void getDisparityRange(int& minimum, int& maximum) except +
|
||||
int getSubpixelFactor() except +
|
||||
bool isImageDisparityPair() except +
|
||||
int getBytesPerPixel(int imageNumber) except +
|
||||
int getBitsPerPixel(int imageNumber) except +
|
||||
int getNumberOfImages() except +
|
||||
int getIndexOf(ImageType what, bool throwIfNotFound) except +
|
||||
bool hasImageType(ImageType what) except +
|
||||
int getExposureTime() except +
|
||||
void getLastSyncPulse(int& seconds, int& microsec) except +
|
||||
# Setters, primarily for deserialization
|
||||
void setWidth(int width) except +
|
||||
void setHeight(int height) except +
|
||||
void setRowStride(int imageNumber, int rowStride) except +
|
||||
void setPixelFormat(int imageNumber, ImageFormat imageFormat) except +
|
||||
void setPixelData(int imageNumber, unsigned char* pixelData) except +
|
||||
void setQMatrix(const float* q) except +
|
||||
void setSequenceNumber(unsigned int num) except +
|
||||
void setTimestamp(int seconds, int microseconds) except +
|
||||
void setDisparityRange(int minimum, int maximum) except +
|
||||
void setSubpixelFactor(int subpixFact) except +
|
||||
void setNumberOfImages(int number) except +
|
||||
void setIndexOf(ImageType what, int idx) except +
|
||||
void setExposureTime(int timeMicrosec) except +
|
||||
void setLastSyncPulse(int seconds, int microsec) except +
|
||||
# Utility functions
|
||||
void writePgmFile(int imageNumber, const char* fileName) except +
|
||||
|
||||
cdef extern from "visiontransfer/imagetransfer.h" namespace "visiontransfer":
|
||||
cdef cppclass ImageTransfer:
|
||||
ImageTransfer(const DeviceInfo& device, int bufferSize, int maxUdpPacketSize) except +
|
||||
bool receiveImageSet(ImageSet& imageSet) except +
|
||||
int getNumDroppedFrames() except +
|
||||
bool isConnected() except +
|
||||
void disconnect() except +
|
||||
string getRemoteAddress() except +
|
||||
|
||||
cdef extern from "visiontransfer/asynctransfer.h" namespace "visiontransfer":
|
||||
cdef cppclass AsyncTransfer:
|
||||
AsyncTransfer(const DeviceInfo& device, int bufferSize, int maxUdpPacketSize) except +
|
||||
bool collectReceivedImageSet(ImageSet& imageSet, double timeout) except +
|
||||
int getNumDroppedFrames() except +
|
||||
bool isConnected() except +
|
||||
void disconnect() except +
|
||||
string getRemoteAddress() except +
|
||||
|
||||
cdef extern from "visiontransfer/reconstruct3d.h" namespace "visiontransfer":
|
||||
cdef cppclass Reconstruct3D:
|
||||
Reconstruct3D() except +
|
||||
float* createPointMap(const unsigned short* dispMap, int width, int height, int rowStride, const float* q, unsigned short minDisparity, int subpixelFactor, unsigned short maxDisparity) except +
|
||||
void projectSinglePoint(int imageX, int imageY, unsigned short disparity, const float* q, float& pointX, float& pointY, float& pointZ, int subpixFactor) except +
|
||||
float* createPointMap(const ImageSet& imageSet, unsigned short minDisparity) except +
|
||||
void writePlyFile(const char* file, const ImageSet& imageSet, double maxZ, bool binary) except +
|
||||
float* createZMap(const ImageSet& imageSet, unsigned short minDisparity, unsigned short maxDisparity) except +
|
||||
|
||||
# Also include auto-generated parameter glue code
|
||||
include "visiontransfer_parameters_cpp_autogen.pxd"
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue