CropRobotFromImage.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package VisionX::ArmarXObjects::CropRobotFromImage
17  * @author Julian Zimmer ( urdbu at student dot kit dot edu )
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "CropRobotFromImage.h"
24 
25 
28 
29 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
30 
31 // IVT
32 #include <Image/ByteImage.h>
33 #include <Image/ImageProcessor.h>
34 #include <Calibration/StereoCalibration.h>
35 #include <Calibration/Calibration.h>
36 #include <Math/LinearAlgebra.h>
37 #include <Math/FloatMatrix.h>
38 
39 
40 namespace armarx
41 {
42 
44  {
45  providerName = getProperty<std::string>("providerName").getValue();
46  usingImageProvider(providerName);
47 
48 
49  usingProxy(getProperty<std::string>("RobotStateComponentName").getValue());
50  cameraFrameName = getProperty<std::string>("cameraFrameName").getValue();
51 
52  backgroundR = getProperty<float>("filterColorR").getValue();
53  backgroundG = getProperty<float>("filterColorG").getValue();
54  backgroundB = getProperty<float>("filterColorB").getValue();
55 
56  dilationStrength = getProperty<int>("dilationStrength").getValue();
57 
58  flipImages = getProperty<bool>("flipImages").getValue();
59  useFullModel = getProperty<bool>("useFullModel").getValue();
60  collisionModelInflationMargin = getProperty<float>("collisionModelInflationMargin").getValue();
61 
62  numResultImages = getProperty<int>("numResultImages").getValue();
63  }
64 
65 
67  {
68 
69  if (getProperty<std::string>("RobotStateComponentName").getValue() != "")
70  {
71  robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(getProperty<std::string>("RobotStateComponentName").getValue());
72  }
73  else
74  {
75  ARMARX_ERROR << "Specification of RobotStateComponentName missing";
76  }
77 
78 
79  //ImageType imageDisplayType = visionx::tools::typeNameToImageType("float-1-channel");
80  visionx::ImageType imageDisplayType = visionx::tools::typeNameToImageType("rgb");
81  //ImageType imageDisplayType = visionx::tools::typeNameToImageType("gray-scale");
82 
83 
84  imageProviderInfo = getImageProvider(providerName, imageDisplayType);
85 
86 
87  numImages = imageProviderInfo.numberImages;
88 
89  images = new CByteImage*[numImages];
90  for (int i = 0 ; i < numImages; i++)
91  {
92  images[i] = visionx::tools::createByteImage(imageProviderInfo);
93  }
94 
95 
96  //calibrationPrx = getTopic<StereoCalibrationInterfacePrx>("StereoCalibrationInterface");
97 
98  visionx::StereoCalibrationProviderInterfacePrx calibrationProvider = visionx::StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderInfo.proxy);
99 
100  if (calibrationProvider)
101  {
102 
103  visionx::StereoCalibration stereoCalibration = calibrationProvider->getStereoCalibration();
104 
105  ::visionx::MonocularCalibration calibrationLeft = stereoCalibration.calibrationLeft;
106  width = calibrationLeft.cameraParam.width;
107  height = calibrationLeft.cameraParam.height;
108  fov = 2.0 * std::atan(width / (2.0 * calibrationLeft.cameraParam.focalLength[1]));
109  //fov = M_PI / 4;
110 
111  ARMARX_INFO << "Using calibration from image provider " << providerName << ". Field of view is: " << fov ;
112 
113  ARMARX_INFO << "Iamge size: (" << width << ", " << height << ").";
114 
115  /*
116  StereoResultImageProviderPtr stereoResultImageProvider = StereoResultImageProviderPtr::dynamicCast(resultImageProvider);
117  stereoResultImageProvider->setStereoCalibration(stereoCalibration, calibrationProvider->getImagesAreUndistorted(), calibrationProvider->getReferenceFrame());
118  */
119  }
120  else
121  {
122  visionx::StereoCalibrationInterfacePrx pointCloudAndStereoCalibrationProvider = visionx::StereoCalibrationInterfacePrx::checkedCast(imageProviderInfo.proxy);
123  if (pointCloudAndStereoCalibrationProvider)
124  {
125  visionx::StereoCalibration stereoCalibration = pointCloudAndStereoCalibrationProvider->getStereoCalibration();
126 
127  ::visionx::MonocularCalibration calibrationLeft = stereoCalibration.calibrationLeft;
128  width = calibrationLeft.cameraParam.width;
129  height = calibrationLeft.cameraParam.height;
130  fov = 2.0 * std::atan(width / (2.0 * calibrationLeft.cameraParam.focalLength[0]));
131  //fov = M_PI / 4;
132 
133  ARMARX_INFO << "Using calibration from image provider " << providerName << ".";
134  }
135  else
136  {
137  ARMARX_IMPORTANT << "image provider " << providerName << " does not have a stereo calibration interface";
138  ARMARX_IMPORTANT << "using default calibration instead";
139 
140  depthCameraCalibration = visionx::tools::createDefaultMonocularCalibration();
141 
142  width = depthCameraCalibration.cameraParam.width;
143  height = depthCameraCalibration.cameraParam.height;
144 
145  //appears to be the correct FOV for the stereo camera (e.g. built into Armar3)
146  //fov = 2.0 * std::atan(width / (2.0 * depthCameraCalibration.cameraParam.focalLength[0]));
147 
148  //appears to be the correct FOV for the depth camera (e.g. mounted on Armar6)
149  fov = M_PI / 4;
150  }
151  }
152 
153  visionx::ImageDimension dimension(images[0]->width, images[0]->height);
154  //enableResultImages(numResultImages, dimension, visionx::tools::typeNameToImageType("float-1-channel"));
155  enableResultImages(numResultImages, dimension, visionx::tools::typeNameToImageType("rgb"));
156 
157 
158 
159  maskRobot = new MaskRobotInImage(robotStateComponent, cameraFrameName, imageProviderInfo.imageFormat, fov, SbColor(backgroundR / 255.f, backgroundG / 255.f, backgroundB / 255.f), flipImages, useFullModel, collisionModelInflationMargin);
160  }
161 
162 
164  {
165 
166  }
167 
168 
170  {
171  for (int i = 0; i < numImages; i++)
172  {
173  delete images[i];
174  }
175  delete [] images;
176  }
177 
179  {
180  ARMARX_VERBOSE << "CropRobotFromImage is processing data!";
181 
182  std::lock_guard<std::mutex> lock(mutex);
183 
184  ARMARX_VERBOSE << "waiting for images";
185  if (!waitForImages(providerName))
186  {
187  ARMARX_WARNING << "Timeout while waiting for images";
188  return;
189  }
190 
191 
192  //get images including the metaInfo which contains the timestamp of the image to synchronize the robot clone
193  ARMARX_VERBOSE << "getting images";
194  armarx::MetaInfoSizeBasePtr metaInfo;
195  if (this->ImageProcessor::getImages(providerName, images, metaInfo) != numImages)
196  {
197  ARMARX_WARNING << "Unable to transfer or read images";
198  return;
199  }
200 
201  CByteImage* maskImage = maskRobot->getMaskImage(metaInfo->timeProvided);
202 
203 
204  //apply dilation
205  if (dilationStrength >= 2)
206  {
207  ::ImageProcessor::Dilate(maskImage, maskImage, dilationStrength);
208  }
209 
210 
211  for (int i = 0; i < numResultImages; i++)
212  {
213  //apply maskImage to the provided image
214  std::uint8_t* pixelsRow = images[i]->pixels;
215  std::uint8_t* maskPixelsRow = maskImage->pixels;
216 
217  for (int y = 0; y < height; y++)
218  {
219  for (int x = 0; x < width; x++)
220  {
221  if (maskPixelsRow[x] == 255)
222  {
223  pixelsRow[x * 3 + 0] = 0;
224  pixelsRow[x * 3 + 1] = 0;
225  pixelsRow[x * 3 + 2] = 0;
226  }
227  }
228 
229  pixelsRow += width * 3;
230  maskPixelsRow += width;
231  }
232  }
233 
234 
235 
236  int imageSize = imageProviderInfo.imageFormat.dimension.width * imageProviderInfo.imageFormat.dimension.height * imageProviderInfo.imageFormat.bytesPerPixel;
237  MetaInfoSizeBasePtr myMetaInfo = new MetaInfoSizeBase(numResultImages * imageSize, numResultImages * imageSize, metaInfo->timeProvided);
238  provideResultImages(images, myMetaInfo);
239 
240  ARMARX_VERBOSE << "CropRobotFromImage process finished";
241  }
242 
244  {
247  }
248 }
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
visionx::ImageProviderInfo::numberImages
int numberImages
Number of images.
Definition: ImageProcessor.h:506
armarx::CropRobotFromImage::onExitImageProcessor
void onExitImageProcessor() override
Exit the ImapeProcessor component.
Definition: CropRobotFromImage.cpp:169
armarx::CropRobotFromImage::onInitImageProcessor
void onInitImageProcessor() override
Setup the vision component.
Definition: CropRobotFromImage.cpp:43
armarx::CropRobotFromImage::createPropertyDefinitions
virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: CropRobotFromImage.cpp:243
armarx::CropRobotFromImage::onConnectImageProcessor
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
Definition: CropRobotFromImage.cpp:66
visionx::ImageProcessor::getImageProvider
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
Definition: ImageProcessor.cpp:152
visionx::ImageProviderInfo::imageFormat
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
Definition: ImageProcessor.h:496
armarx::CropRobotFromImage::process
void process() override
Process the vision component.
Definition: CropRobotFromImage.cpp:178
armarx::CropRobotFromImagePropertyDefinitions
Definition: CropRobotFromImage.h:61
visionx::tools::createByteImage
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
M_PI
#define M_PI
Definition: MathTools.h:17
visionx::ImageProcessor::usingImageProvider
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
Definition: ImageProcessor.cpp:117
armarx::CropRobotFromImage::onDisconnectImageProcessor
void onDisconnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component looses network ...
Definition: CropRobotFromImage.cpp:163
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::MaskRobotInImage
A brief description.
Definition: MaskRobotInImage.h:62
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
CMakePackageFinder.h
visionx::ImageProviderInfo::proxy
ImageProviderInterfacePrx proxy
proxy to image provider
Definition: ImageProcessor.h:472
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
IceUtil::Handle< class PropertyDefinitionContainer >
visionx::ImageProcessor::enableResultImages
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
Definition: ImageProcessor.cpp:227
visionx::tools::typeNameToImageType
ImageType typeNameToImageType(const std::string &imageTypeName)
Converts an image type name as string into an ImageType integer.
Definition: TypeMapping.cpp:42
CropRobotFromImage.h
visionx::ImageProcessor::provideResultImages
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
Definition: ImageProcessor.cpp:245
armarx::MaskRobotInImage::getMaskImage
CByteImage * getMaskImage(Ice::Long timestamp)
Definition: MaskRobotInImage.cpp:110
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
ArmarXDataPath.h
visionx::tools::createDefaultMonocularCalibration
MonocularCalibration createDefaultMonocularCalibration()
Creates a MonocularCalibration with all parameters set to a neutral value.
Definition: ImageUtil.cpp:237
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:151
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
visionx::ImageProcessor::waitForImages
bool waitForImages(int milliseconds=1000)
Wait for new images.
Definition: ImageProcessor.cpp:275