31#include <opencv2/imgproc.hpp>
33#include <Ice/Config.h>
34#include <Ice/Current.h>
35#include <IceUtil/Time.h>
39#include <visiontransfer/deviceenumeration.h>
40#include <visiontransfer/deviceinfo.h>
41#include <visiontransfer/deviceparameters.h>
42#include <visiontransfer/imageset.h>
43#include <visiontransfer/imagetransfer.h>
46#include <Image/ByteImage.h>
47#include <Image/ImageProcessor.h>
58#include <VisionX/interface/components/Calibration.h>
59#include <VisionX/interface/core/DataTypes.h>
69 using visiontransfer::DeviceEnumeration;
70 using visiontransfer::DeviceInfo;
71 using visiontransfer::DeviceParameters;
73 DeviceEnumeration deviceEnum;
74 DeviceEnumeration::DeviceList devices = deviceEnum.discoverDevices();
75 if (devices.size() == 0)
77 ARMARX_INFO <<
"No Nerian Vision devices detected! Shutting down...";
79 throw armarx::LocalException(
"No Nerian Vision devices detected!");
83 auto deviceModel = device.getModel();
88 ARMARX_INFO <<
"Using Nerian Vision device: " << device.toString();
92 int numImages = (deviceModel == DeviceInfo::RUBY && enableColorCamera) ? 3 : 2;
95 visionx::ImageDimension dimensions;
97 std::unique_ptr<DeviceParameters> parameterPtr =
nullptr;
100 parameterPtr = std::make_unique<DeviceParameters>(device);
102 catch (
const std::exception& e)
105 <<
" (" << e.what() <<
")";
111 auto dim = parameterPtr->getParameter(
"RT_output_image_size").getTensorData();
112 dimensions.width =
static_cast<int>(dim[0]);
113 dimensions.height =
static_cast<int>(dim[1]);
115 catch (
const std::exception& e)
117 ARMARX_INFO <<
"Failed to get dimension from device parameters. Using app property "
118 "`dimensions` as fallback."
119 <<
" (" << e.what() <<
")";
123 ARMARX_DEBUG <<
"Using image dimensions: " << dimensions.width <<
"x" << dimensions.height;
124 setImageFormat(dimensions, visionx::eRgb, visionx::eBayerPatternRg);
131 if (deviceModel == DeviceInfo::DeviceModel::RUBY)
133 parameterPtr->setParameter(
"output_channel_left_enabled",
true);
134 parameterPtr->setParameter(
"output_channel_right_enabled",
true);
135 parameterPtr->setParameter(
"output_channel_color_enabled", enableColorCamera);
136 parameterPtr->setParameter(
"output_channel_color_mode", 0);
137 parameterPtr->setParameter(
"output_channel_disparity_enabled",
false);
140 parameterPtr->setOperationMode(rectifyImages
141 ? visiontransfer::DeviceParameters::RECTIFY
142 : DeviceParameters::OperationMode::PASS_THROUGH);
144 catch (
const std::exception& e)
146 ARMARX_INFO <<
"Failed to configure device." <<
" (" << e.what() <<
")";
148 <<
"If the images are not displayed as expected, manual configuration of the "
149 <<
"device may be necessary. To do this, open the web interface of the device at "
150 << device.getIpAddress() <<
" and verify/set the following settings: "
151 << (deviceModel == DeviceInfo::DeviceModel::RUBY
152 ?
"Output channels [left, right, color] are enabled and the "
153 "disparity output channel is disabled. Optionally, change the "
154 "color output mode to not use projection in order to avoid artifacts."
156 <<
"Operation mode is set to " << (rectifyImages ?
"RECTIFY" :
"PASS_THROUGH")
169 imageProcessingTask->start();
175 using visiontransfer::DeviceParameters;
176 using visiontransfer::ImageSet;
177 using visiontransfer::ImageTransfer;
181 std::unique_ptr<ImageTransfer> imageTransferPtr =
nullptr;
184 imageTransferPtr = std::make_unique<ImageTransfer>(device);
186 catch (
const std::exception& e)
189 <<
" (" << e.what() <<
")";
193 if (imageTransferPtr ==
nullptr)
199 while (not imageProcessingTask->isStopped())
206 status = imageTransferPtr->receiveImageSet(imageSet);
208 catch (
const std::exception& e)
211 <<
" (" << e.what() <<
")";
222 if (numImages != imageSet.getNumberOfImages())
225 << imageSet.getNumberOfImages()
226 <<
" images. Please verify the device and component configurations.";
230 if (!imageSet.hasImageType(ImageSet::ImageType::IMAGE_LEFT) ||
231 !imageSet.hasImageType(ImageSet::ImageType::IMAGE_RIGHT) ||
232 (numImages == 3 && !imageSet.hasImageType(ImageSet::ImageType::IMAGE_COLOR)))
235 <<
"Received image set does not contain the expected image types. "
236 "Please verify the device and component configurations, then "
237 "restart this component.";
244 for (
int i = 0; i < numImages; i++)
246 auto imageType = imageSet.getImageType(i);
247 auto imageFormat = imageSet.getPixelFormat(imageType);
249 if (imageType == ImageSet::ImageType::IMAGE_DISPARITY ||
250 imageType == ImageSet::ImageType::IMAGE_UNDEFINED ||
251 (!enableColorCamera && imageType == ImageSet::ImageType::IMAGE_COLOR))
254 << ImageSet::getNameForImageType(imageType);
260 if (imageFormat == ImageSet::ImageFormat::FORMAT_8_BIT_MONO)
262 cv::Mat grayscale_image;
263 imageSet.toOpenCVImage(i, grayscale_image);
264 cv::cvtColor(grayscale_image, bgr_image, cv::COLOR_GRAY2BGR);
266 else if (imageFormat == ImageSet::ImageFormat::FORMAT_8_BIT_RGB)
268 imageSet.toOpenCVImage(i, bgr_image,
true);
273 << ImageSet::getNameForImageFormat(imageFormat);
286 imageSet.getTimestamp(t_s, t_us);
288 IceUtil::Time::seconds(t_s) + IceUtil::Time::microSeconds(t_us);
304 imageProcessingTask->stop(
false);
305 ARMARX_DEBUG <<
"Waiting for image processing thread to stop...";
306 imageProcessingTask->waitForStop();
318 const Ice::Current& )
336 return rectifyImages;
342 StereoCalibration calibration;
347 calibration.rectificationHomographyLeft = calibration.rectificationHomographyRight =
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 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 setNumberImages(int numberImages)
Sets the number of images on each capture.
void ** imageBuffers
Image buffer memory.
bool getImagesAreUndistorted(const Ice::Current &c) override
void stopCapture(const Ice::Current &c) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectImageProvider() override
This is called when the Component::onConnectComponent() setup is called.
visionx::StereoCalibration getStereoCalibration(const Ice::Current &c) override
std::string getReferenceFrame(const Ice::Current &c) override
static std::string getNameForDeviceModel(const visiontransfer::DeviceInfo::DeviceModel &model)
void startCapture(Ice::Float framesPerSecond, const Ice::Current &c) override
void onInitImageProvider() override
This is called when the Component::onInitComponent() is called.
void onExitImageProvider() override
This is called when the Component::onExitComponent() setup is called.
void onDisconnectImageProvider() override
void runImagePublishing()
#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.
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.