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 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
26 
29 
30 // IVT
31 #include <Calibration/Calibration.h>
32 #include <Calibration/StereoCalibration.h>
33 #include <Image/ByteImage.h>
34 #include <Image/ImageProcessor.h>
35 #include <Math/FloatMatrix.h>
36 #include <Math/LinearAlgebra.h>
37 
38 namespace armarx
39 {
40 
41  void
43  {
44  providerName = getProperty<std::string>("providerName").getValue();
45  usingImageProvider(providerName);
46 
47 
48  usingProxy(getProperty<std::string>("RobotStateComponentName").getValue());
49  cameraFrameName = getProperty<std::string>("cameraFrameName").getValue();
50 
51  backgroundR = getProperty<float>("filterColorR").getValue();
52  backgroundG = getProperty<float>("filterColorG").getValue();
53  backgroundB = getProperty<float>("filterColorB").getValue();
54 
55  dilationStrength = getProperty<int>("dilationStrength").getValue();
56 
57  flipImages = getProperty<bool>("flipImages").getValue();
58  useFullModel = getProperty<bool>("useFullModel").getValue();
59  collisionModelInflationMargin =
60  getProperty<float>("collisionModelInflationMargin").getValue();
61 
62  numResultImages = getProperty<int>("numResultImages").getValue();
63  }
64 
65  void
67  {
68 
69  if (getProperty<std::string>("RobotStateComponentName").getValue() != "")
70  {
71  robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(
72  getProperty<std::string>("RobotStateComponentName").getValue());
73  }
74  else
75  {
76  ARMARX_ERROR << "Specification of RobotStateComponentName missing";
77  }
78 
79 
80  //ImageType imageDisplayType = visionx::tools::typeNameToImageType("float-1-channel");
81  visionx::ImageType imageDisplayType = visionx::tools::typeNameToImageType("rgb");
82  //ImageType imageDisplayType = visionx::tools::typeNameToImageType("gray-scale");
83 
84 
85  imageProviderInfo = getImageProvider(providerName, imageDisplayType);
86 
87 
88  numImages = imageProviderInfo.numberImages;
89 
90  images = new CByteImage*[numImages];
91  for (int i = 0; i < numImages; i++)
92  {
93  images[i] = visionx::tools::createByteImage(imageProviderInfo);
94  }
95 
96 
97  //calibrationPrx = getTopic<StereoCalibrationInterfacePrx>("StereoCalibrationInterface");
98 
99  visionx::StereoCalibrationProviderInterfacePrx calibrationProvider =
100  visionx::StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderInfo.proxy);
101 
102  if (calibrationProvider)
103  {
104 
105  visionx::StereoCalibration stereoCalibration =
106  calibrationProvider->getStereoCalibration();
107 
108  ::visionx::MonocularCalibration calibrationLeft = stereoCalibration.calibrationLeft;
109  width = calibrationLeft.cameraParam.width;
110  height = calibrationLeft.cameraParam.height;
111  fov = 2.0 * std::atan(width / (2.0 * calibrationLeft.cameraParam.focalLength[1]));
112  //fov = M_PI / 4;
113 
114  ARMARX_INFO << "Using calibration from image provider " << providerName
115  << ". Field of view is: " << fov;
116 
117  ARMARX_INFO << "Iamge size: (" << width << ", " << height << ").";
118 
119  /*
120  StereoResultImageProviderPtr stereoResultImageProvider = StereoResultImageProviderPtr::dynamicCast(resultImageProvider);
121  stereoResultImageProvider->setStereoCalibration(stereoCalibration, calibrationProvider->getImagesAreUndistorted(), calibrationProvider->getReferenceFrame());
122  */
123  }
124  else
125  {
126  visionx::StereoCalibrationInterfacePrx pointCloudAndStereoCalibrationProvider =
127  visionx::StereoCalibrationInterfacePrx::checkedCast(imageProviderInfo.proxy);
128  if (pointCloudAndStereoCalibrationProvider)
129  {
130  visionx::StereoCalibration stereoCalibration =
131  pointCloudAndStereoCalibrationProvider->getStereoCalibration();
132 
133  ::visionx::MonocularCalibration calibrationLeft = stereoCalibration.calibrationLeft;
134  width = calibrationLeft.cameraParam.width;
135  height = calibrationLeft.cameraParam.height;
136  fov = 2.0 * std::atan(width / (2.0 * calibrationLeft.cameraParam.focalLength[0]));
137  //fov = M_PI / 4;
138 
139  ARMARX_INFO << "Using calibration from image provider " << providerName << ".";
140  }
141  else
142  {
143  ARMARX_IMPORTANT << "image provider " << providerName
144  << " does not have a stereo calibration interface";
145  ARMARX_IMPORTANT << "using default calibration instead";
146 
147  depthCameraCalibration = visionx::tools::createDefaultMonocularCalibration();
148 
149  width = depthCameraCalibration.cameraParam.width;
150  height = depthCameraCalibration.cameraParam.height;
151 
152  //appears to be the correct FOV for the stereo camera (e.g. built into Armar3)
153  //fov = 2.0 * std::atan(width / (2.0 * depthCameraCalibration.cameraParam.focalLength[0]));
154 
155  //appears to be the correct FOV for the depth camera (e.g. mounted on Armar6)
156  fov = M_PI / 4;
157  }
158  }
159 
160  visionx::ImageDimension dimension(images[0]->width, images[0]->height);
161  //enableResultImages(numResultImages, dimension, visionx::tools::typeNameToImageType("float-1-channel"));
162  enableResultImages(numResultImages, dimension, visionx::tools::typeNameToImageType("rgb"));
163 
164 
165  maskRobot = new MaskRobotInImage(
166  robotStateComponent,
167  cameraFrameName,
168  imageProviderInfo.imageFormat,
169  fov,
170  SbColor(backgroundR / 255.f, backgroundG / 255.f, backgroundB / 255.f),
171  flipImages,
172  useFullModel,
173  collisionModelInflationMargin);
174  }
175 
176  void
178  {
179  }
180 
181  void
183  {
184  for (int i = 0; i < numImages; i++)
185  {
186  delete images[i];
187  }
188  delete[] images;
189  }
190 
191  void
193  {
194  ARMARX_VERBOSE << "CropRobotFromImage is processing data!";
195 
196  std::lock_guard<std::mutex> lock(mutex);
197 
198  ARMARX_VERBOSE << "waiting for images";
199  if (!waitForImages(providerName))
200  {
201  ARMARX_WARNING << "Timeout while waiting for images";
202  return;
203  }
204 
205 
206  //get images including the metaInfo which contains the timestamp of the image to synchronize the robot clone
207  ARMARX_VERBOSE << "getting images";
208  armarx::MetaInfoSizeBasePtr metaInfo;
209  if (this->ImageProcessor::getImages(providerName, images, metaInfo) != numImages)
210  {
211  ARMARX_WARNING << "Unable to transfer or read images";
212  return;
213  }
214 
215  CByteImage* maskImage = maskRobot->getMaskImage(metaInfo->timeProvided);
216 
217 
218  //apply dilation
219  if (dilationStrength >= 2)
220  {
221  ::ImageProcessor::Dilate(maskImage, maskImage, dilationStrength);
222  }
223 
224 
225  for (int i = 0; i < numResultImages; i++)
226  {
227  //apply maskImage to the provided image
228  std::uint8_t* pixelsRow = images[i]->pixels;
229  std::uint8_t* maskPixelsRow = maskImage->pixels;
230 
231  for (int y = 0; y < height; y++)
232  {
233  for (int x = 0; x < width; x++)
234  {
235  if (maskPixelsRow[x] == 255)
236  {
237  pixelsRow[x * 3 + 0] = 0;
238  pixelsRow[x * 3 + 1] = 0;
239  pixelsRow[x * 3 + 2] = 0;
240  }
241  }
242 
243  pixelsRow += width * 3;
244  maskPixelsRow += width;
245  }
246  }
247 
248 
249  int imageSize = imageProviderInfo.imageFormat.dimension.width *
250  imageProviderInfo.imageFormat.dimension.height *
251  imageProviderInfo.imageFormat.bytesPerPixel;
252  MetaInfoSizeBasePtr myMetaInfo = new MetaInfoSizeBase(
253  numResultImages * imageSize, numResultImages * imageSize, metaInfo->timeProvided);
254  provideResultImages(images, myMetaInfo);
255 
256  ARMARX_VERBOSE << "CropRobotFromImage process finished";
257  }
258 
261  {
264  }
265 } // namespace armarx
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
visionx::ImageProviderInfo::numberImages
int numberImages
Number of images.
Definition: ImageProcessor.h:519
armarx::CropRobotFromImage::onExitImageProcessor
void onExitImageProcessor() override
Exit the ImapeProcessor component.
Definition: CropRobotFromImage.cpp:182
armarx::CropRobotFromImage::onInitImageProcessor
void onInitImageProcessor() override
Setup the vision component.
Definition: CropRobotFromImage.cpp:42
armarx::CropRobotFromImage::createPropertyDefinitions
virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: CropRobotFromImage.cpp:260
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:167
visionx::ImageProviderInfo::imageFormat
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
Definition: ImageProcessor.h:509
armarx::CropRobotFromImage::process
void process() override
Process the vision component.
Definition: CropRobotFromImage.cpp:192
armarx::CropRobotFromImagePropertyDefinitions
Definition: CropRobotFromImage.h:56
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:128
armarx::CropRobotFromImage::onDisconnectImageProcessor
void onDisconnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component looses network ...
Definition: CropRobotFromImage.cpp:177
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
armarx::MaskRobotInImage
A brief description.
Definition: MaskRobotInImage.h:59
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:79
CMakePackageFinder.h
visionx::ImageProviderInfo::proxy
ImageProviderInterfacePrx proxy
proxy to image provider
Definition: ImageProcessor.h:485
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
IceUtil::Handle< class PropertyDefinitionContainer >
visionx::ImageProcessor::enableResultImages
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
Definition: ImageProcessor.cpp:251
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:274
armarx::MaskRobotInImage::getMaskImage
CByteImage * getMaskImage(Ice::Long timestamp)
Definition: MaskRobotInImage.cpp:119
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:35
ArmarXDataPath.h
visionx::tools::createDefaultMonocularCalibration
MonocularCalibration createDefaultMonocularCalibration()
Creates a MonocularCalibration with all parameters set to a neutral value.
Definition: ImageUtil.cpp:265
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:154
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
visionx::ImageProcessor::waitForImages
bool waitForImages(int milliseconds=1000)
Wait for new images.
Definition: ImageProcessor.cpp:309