34#include <pcl/common/impl/io.hpp>
35#include <pcl/point_cloud.h>
37#include <opencv2/opencv.hpp>
39#include <Ice/Config.h>
40#include <Ice/Current.h>
41#include <IceUtil/Time.h>
45#include <visiontransfer/deviceenumeration.h>
46#include <visiontransfer/deviceinfo.h>
47#include <visiontransfer/deviceparameters.h>
48#include <visiontransfer/imageset.h>
49#include <visiontransfer/imagetransfer.h>
50#include <visiontransfer/reconstruct3d.h>
53#include <Image/ByteImage.h>
54#include <Image/ImageProcessor.h>
68#include <VisionX/interface/components/Calibration.h>
69#include <VisionX/interface/core/DataTypes.h>
86 using visiontransfer::DeviceEnumeration;
87 using visiontransfer::DeviceInfo;
88 using visiontransfer::DeviceParameters;
90 DeviceEnumeration deviceEnum;
91 DeviceEnumeration::DeviceList devices = deviceEnum.discoverDevices();
92 if (devices.size() == 0)
94 ARMARX_INFO <<
"No Nerian Vision devices detected! Shutting down...";
96 throw armarx::LocalException(
"No Nerian Vision devices detected!");
100 auto deviceModel = device.getModel();
105 ARMARX_INFO <<
"Using Nerian Vision device: " << device.toString();
107 if (deviceModel != DeviceInfo::DeviceModel::RUBY)
110 <<
" is currently not supported for this component! Shutting down...";
112 throw armarx::LocalException(
"Unsupported device model!");
117 std::unique_ptr<DeviceParameters> parameterPtr =
nullptr;
120 parameterPtr = std::make_unique<DeviceParameters>(device);
122 catch (
const std::exception& e)
125 <<
" (" << e.what() <<
")";
131 auto dim = parameterPtr->getParameter(
"RT_output_image_size").getTensorData();
132 dimensions.width =
static_cast<int>(dim[0]);
133 dimensions.height =
static_cast<int>(dim[1]);
135 catch (
const std::exception& e)
137 ARMARX_INFO <<
"Failed to get dimension from device parameters. Using app property "
138 "`dimensions` as fallback."
139 <<
" (" << e.what() <<
")";
143 ARMARX_DEBUG <<
"Using image dimensions: " << dimensions.width <<
"x" << dimensions.height;
144 setImageFormat(dimensions, visionx::eRgb, visionx::eBayerPatternRg);
150 parameterPtr->setParameter(
"output_channel_left_enabled",
false);
151 parameterPtr->setParameter(
"output_channel_right_enabled",
false);
152 parameterPtr->setParameter(
"output_channel_color_enabled",
true);
153 parameterPtr->setParameter(
"output_channel_color_mode", 0);
154 parameterPtr->setParameter(
"output_channel_disparity_enabled",
true);
155 parameterPtr->setOperationMode(DeviceParameters::OperationMode::STEREO_MATCHING);
157 catch (
const std::exception& e)
159 ARMARX_INFO <<
"Failed to configure device." <<
" (" << e.what() <<
")";
161 <<
"Manual configuration of the device may be necessary. To do this, open the web "
162 "interface of the device at "
163 << device.getIpAddress() <<
" and verify/set the following settings: "
164 <<
"Output channels [color, disparity] are enabled and the channels [left, right] "
165 "are disabled. The Operation mode should be set to STEREO_MATCHING.";
172 pointcloud = std::make_unique<pcl::PointCloud<CloudPointType>>();
190 processingTask->start();
202 using visiontransfer::DeviceParameters;
203 using visiontransfer::ImageSet;
204 using visiontransfer::ImageTransfer;
206 visiontransfer::Reconstruct3D reconstructor;
210 std::unique_ptr<ImageTransfer> imageTransferPtr =
nullptr;
213 imageTransferPtr = std::make_unique<ImageTransfer>(device);
215 catch (
const std::exception& e)
218 <<
" (" << e.what() <<
")";
222 if (imageTransferPtr ==
nullptr)
228 while (not processingTask->isStopped())
235 status = imageTransferPtr->receiveImageSet(imageSet);
237 catch (
const std::exception& e)
240 <<
" (" << e.what() <<
")";
253 if (numImages != imageSet.getNumberOfImages())
256 << imageSet.getNumberOfImages()
257 <<
" images. Please verify the device and component configurations.";
261 if (!imageSet.hasImageType(ImageSet::ImageType::IMAGE_COLOR) ||
262 !imageSet.hasImageType(ImageSet::ImageType::IMAGE_DISPARITY))
265 <<
"Received image set does not contain the expected image types "
266 "(color, disparity). Please verify the device and component "
267 "configurations, then restart this component.";
273 int index_color = imageSet.getIndexOf(ImageSet::ImageType::IMAGE_COLOR);
274 if (imageSet.getPixelFormat(index_color) != ImageSet::ImageFormat::FORMAT_8_BIT_RGB)
278 <<
"Received unexpected image format for color image. Expected 8-bit RGB.";
282 int index_disparity = imageSet.getIndexOf(ImageSet::ImageType::IMAGE_DISPARITY);
283 if (imageSet.getPixelFormat(index_disparity) !=
284 ImageSet::ImageFormat::FORMAT_12_BIT_MONO)
287 <<
"Received unexpected image format for disparity image. Expected "
297 imageSet.toOpenCVImage(index_color, bgr_image,
true);
306 const int dw = imageSet.getWidth();
307 const int dh = imageSet.getHeight();
309 imageBuffers[1] =
new CByteImage(dw, dh, CByteImage::ImageType::eRGB24);
312 auto* result_depth_buffer = depth_image->pixels;
313 const auto* pixelData = imageSet.getPixelData(index_disparity);
314 const auto* depth_buffer =
reinterpret_cast<const uint16_t*
>(pixelData);
318 for (
int y = 0; y < dh; ++y)
320 for (
int x = 0;
x < dw; ++
x)
322 uint16_t depth_value = depth_buffer[index_2];
324 result_depth_buffer[
index],
325 result_depth_buffer[
index + 1],
326 result_depth_buffer[
index + 2]);
340 auto temp = reconstructor.createXYZRGBCloud(imageSet,
"");
342 pointcloud->header.stamp = temp->header.stamp;
343 pointcloud->is_dense = temp->is_dense;
344 pointcloud->width = temp->width;
345 pointcloud->height = temp->height;
346 pointcloud->points.resize(pointcloud->width * pointcloud->height);
347 pcl::detail::copyPointCloudMemcpy(*temp, *pointcloud);
350 for (
auto& p : pointcloud->points)
364 if (z <= max_depth and z != 0)
370 p.z = std::numeric_limits<float>::quiet_NaN();
381 imageSet.getTimestamp(t_s, t_us);
383 IceUtil::Time::seconds(t_s) + IceUtil::Time::microSeconds(t_us);
413 processingTask->stop(
false);
414 ARMARX_DEBUG <<
"Waiting for processing thread to stop...";
415 processingTask->waitForStop();
437 visionx::StereoCalibration
440 StereoCalibration stereo_calibration;
446 auto& colorDistortionParams = stereo_calibration.calibrationLeft.cameraParam.distortion;
447 std::fill(colorDistortionParams.begin(), colorDistortionParams.end(), 0);
448 auto& depthDistortionParams = stereo_calibration.calibrationRight.cameraParam.distortion;
449 std::fill(depthDistortionParams.begin(), depthDistortionParams.end(), 0);
451 stereo_calibration.rectificationHomographyLeft =
452 stereo_calibration.rectificationHomographyRight =
455 return stereo_calibration;
485 const Ice::Current& )
491 const Ice::Current& )
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
std::string getName() const
Retrieve name of object.
void setMetaInfo(const std::string &id, const VariantBasePtr &value)
Allows to set meta information that can be queried live via Ice interface on the ArmarXManager.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
IceUtil::Handle< RunningTask< T > > pointer_type
Shared pointer type for convenience.
The Variant class is described here: Variants.
void onInitComponent() override
void onDisconnectComponent() override
Hook for subclass.
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
int getNumberImages(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve number of images handled by this provider.
void provideImages(void **inputBuffers, const IceUtil::Time &imageTimestamp=IceUtil::Time())
send images raw.
void onConnectComponent() override
void setNumberImages(int numberImages)
Sets the number of images on each capture.
void ** imageBuffers
Image buffer memory.
void onExitComponent() override
void onInitComponent() override
Pure virtual hook for the subclass.
void stopCapture(const Ice::Current &c) override
bool isCaptureEnabled(const Ice::Current &c) override
void onDisconnectComponent() override
Hook for subclass.
void changeFrameRate(Ice::Float framesPerSecond, const Ice::Current &c) override
void onConnectPointCloudProvider() override
This is called when the Component::onConnectComponent() setup is called.
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectImageProvider() override
This is called when the Component::onConnectComponent() setup is called.
void onInitPointCloudProvider() override
This is called when the Component::onInitComponent() is called.
std::string getReferenceFrame(const Ice::Current &c) override
void runImageAndPointCloudPublishing()
void startCaptureForNumFrames(int numFrames, const Ice::Current &c) override
void startCapture(const Ice::Current &c) override
void onConnectComponent() override
Pure virtual hook for the subclass.
static std::string getNameForDeviceModel(const visiontransfer::DeviceInfo::DeviceModel &model)
visionx::StereoCalibration getStereoCalibration(const Ice::Current &c) override
bool getImagesAreUndistorted(const ::Ice::Current &c) override
void onInitImageProvider() override
This is called when the Component::onInitComponent() is called.
void onExitComponent() override
Hook for subclass.
void onExitImageProvider() override
This is called when the Component::onExitComponent() setup is called.
void onExitPointCloudProvider() override
This is called when the Component::onExitComponent() setup is called.
void onDisconnectImageProvider() override
void onInitComponent() override
MetaPointCloudFormatPtr getPointCloudFormat(const Ice::Current &c=Ice::emptyCurrent) override
Returns the point cloud format info struct via Ice.
void providePointCloud(PointCloudPtrT pointCloudPtr)
offer the new point cloud.
void onConnectComponent() override
void onExitComponent() override
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void convert(const CByteImage &in, cv::Mat &out)
Converts an IVT CByteImage to OpenCV's BGR Mat.