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
38namespace 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 {
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
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
265} // namespace armarx
#define M_PI
Definition MathTools.h:17
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
void onExitImageProcessor() override
Exit the ImapeProcessor component.
virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void process() override
Process the vision component.
void onInitImageProcessor() override
Setup the vision component.
void onDisconnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component looses network ...
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
A brief description.
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
bool waitForImages(int milliseconds=1000)
Wait for new images.
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
ImageType typeNameToImageType(const std::string &imageTypeName)
Converts an image type name as string into an ImageType integer.
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
MonocularCalibration createDefaultMonocularCalibration()
Creates a MonocularCalibration with all parameters set to a neutral value.