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
26
27#include <VirtualRobot/CollisionDetection/CollisionModel.h>
28
31
32// IVT
33#include <Calibration/Calibration.h>
34#include <Calibration/StereoCalibration.h>
35#include <Image/ByteImage.h>
36#include <Image/ImageProcessor.h>
37#include <Math/FloatMatrix.h>
38#include <Math/LinearAlgebra.h>
39
40namespace armarx
41{
42
43 void
45 {
46 providerName = getProperty<std::string>("providerName").getValue();
47 usingImageProvider(providerName);
48
49
50 usingProxy(getProperty<std::string>("RobotStateComponentName").getValue());
51 cameraFrameName = getProperty<std::string>("cameraFrameName").getValue();
52
53 backgroundR = getProperty<float>("filterColorR").getValue();
54 backgroundG = getProperty<float>("filterColorG").getValue();
55 backgroundB = getProperty<float>("filterColorB").getValue();
56
57 dilationStrength = getProperty<int>("dilationStrength").getValue();
58
59 flipImages = getProperty<bool>("flipImages").getValue();
60 useFullModel = getProperty<bool>("useFullModel").getValue();
61 collisionModelInflationMargin =
62 getProperty<float>("collisionModelInflationMargin").getValue();
63
64 numResultImages = getProperty<int>("numResultImages").getValue();
65 }
66
67 void
69 {
70
71 if (getProperty<std::string>("RobotStateComponentName").getValue() != "")
72 {
74 getProperty<std::string>("RobotStateComponentName").getValue());
75 }
76 else
77 {
78 ARMARX_ERROR << "Specification of RobotStateComponentName missing";
79 }
80
81
82 //ImageType imageDisplayType = visionx::tools::typeNameToImageType("float-1-channel");
83 visionx::ImageType imageDisplayType = visionx::tools::typeNameToImageType("rgb");
84 //ImageType imageDisplayType = visionx::tools::typeNameToImageType("gray-scale");
85
86
87 imageProviderInfo = getImageProvider(providerName, imageDisplayType);
88
89
90 numImages = imageProviderInfo.numberImages;
91
92 images = new CByteImage*[numImages];
93 for (int i = 0; i < numImages; i++)
94 {
95 images[i] = visionx::tools::createByteImage(imageProviderInfo);
96 }
97
98
99 //calibrationPrx = getTopic<StereoCalibrationInterfacePrx>("StereoCalibrationInterface");
100
101 visionx::StereoCalibrationProviderInterfacePrx calibrationProvider =
102 visionx::StereoCalibrationProviderInterfacePrx::checkedCast(imageProviderInfo.proxy);
103
104 if (calibrationProvider)
105 {
106
107 visionx::StereoCalibration stereoCalibration =
108 calibrationProvider->getStereoCalibration();
109
110 ::visionx::MonocularCalibration calibrationLeft = stereoCalibration.calibrationLeft;
111 width = calibrationLeft.cameraParam.width;
112 height = calibrationLeft.cameraParam.height;
113 fov = 2.0 * std::atan(width / (2.0 * calibrationLeft.cameraParam.focalLength[1]));
114 //fov = M_PI / 4;
115
116 ARMARX_INFO << "Using calibration from image provider " << providerName
117 << ". Field of view is: " << fov;
118
119 ARMARX_INFO << "Iamge size: (" << width << ", " << height << ").";
120
121 /*
122 StereoResultImageProviderPtr stereoResultImageProvider = StereoResultImageProviderPtr::dynamicCast(resultImageProvider);
123 stereoResultImageProvider->setStereoCalibration(stereoCalibration, calibrationProvider->getImagesAreUndistorted(), calibrationProvider->getReferenceFrame());
124 */
125 }
126 else
127 {
128 visionx::StereoCalibrationInterfacePrx pointCloudAndStereoCalibrationProvider =
129 visionx::StereoCalibrationInterfacePrx::checkedCast(imageProviderInfo.proxy);
130 if (pointCloudAndStereoCalibrationProvider)
131 {
132 visionx::StereoCalibration stereoCalibration =
133 pointCloudAndStereoCalibrationProvider->getStereoCalibration();
134
135 ::visionx::MonocularCalibration calibrationLeft = stereoCalibration.calibrationLeft;
136 width = calibrationLeft.cameraParam.width;
137 height = calibrationLeft.cameraParam.height;
138 fov = 2.0 * std::atan(width / (2.0 * calibrationLeft.cameraParam.focalLength[0]));
139 //fov = M_PI / 4;
140
141 ARMARX_INFO << "Using calibration from image provider " << providerName << ".";
142 }
143 else
144 {
145 ARMARX_IMPORTANT << "image provider " << providerName
146 << " does not have a stereo calibration interface";
147 ARMARX_IMPORTANT << "using default calibration instead";
148
149 depthCameraCalibration = visionx::tools::createDefaultMonocularCalibration();
150
151 width = depthCameraCalibration.cameraParam.width;
152 height = depthCameraCalibration.cameraParam.height;
153
154 //appears to be the correct FOV for the stereo camera (e.g. built into Armar3)
155 //fov = 2.0 * std::atan(width / (2.0 * depthCameraCalibration.cameraParam.focalLength[0]));
156
157 //appears to be the correct FOV for the depth camera (e.g. mounted on Armar6)
158 fov = M_PI / 4;
159 }
160 }
161
162 visionx::ImageDimension dimension(images[0]->width, images[0]->height);
163 //enableResultImages(numResultImages, dimension, visionx::tools::typeNameToImageType("float-1-channel"));
164 enableResultImages(numResultImages, dimension, visionx::tools::typeNameToImageType("rgb"));
165
166
167 maskRobot = new MaskRobotInImage(
168 robotStateComponent,
169 cameraFrameName,
170 imageProviderInfo.imageFormat,
171 fov,
172 SbColor(backgroundR / 255.f, backgroundG / 255.f, backgroundB / 255.f),
173 flipImages,
174 useFullModel,
175 collisionModelInflationMargin);
176 }
177
178 void
182
183 void
185 {
186 for (int i = 0; i < numImages; i++)
187 {
188 delete images[i];
189 }
190 delete[] images;
191 }
192
193 void
195 {
196 ARMARX_VERBOSE << "CropRobotFromImage is processing data!";
197
198 std::lock_guard<std::mutex> lock(mutex);
199
200 ARMARX_VERBOSE << "waiting for images";
201 if (!waitForImages(providerName))
202 {
203 ARMARX_WARNING << "Timeout while waiting for images";
204 return;
205 }
206
207
208 //get images including the metaInfo which contains the timestamp of the image to synchronize the robot clone
209 ARMARX_VERBOSE << "getting images";
210 armarx::MetaInfoSizeBasePtr metaInfo;
211 if (this->ImageProcessor::getImages(providerName, images, metaInfo) != numImages)
212 {
213 ARMARX_WARNING << "Unable to transfer or read images";
214 return;
215 }
216
217 CByteImage* maskImage = maskRobot->getMaskImage(metaInfo->timeProvided);
218
219
220 //apply dilation
221 if (dilationStrength >= 2)
222 {
223 ::ImageProcessor::Dilate(maskImage, maskImage, dilationStrength);
224 }
225
226
227 for (int i = 0; i < numResultImages; i++)
228 {
229 //apply maskImage to the provided image
230 std::uint8_t* pixelsRow = images[i]->pixels;
231 std::uint8_t* maskPixelsRow = maskImage->pixels;
232
233 for (int y = 0; y < height; y++)
234 {
235 for (int x = 0; x < width; x++)
236 {
237 if (maskPixelsRow[x] == 255)
238 {
239 pixelsRow[x * 3 + 0] = 0;
240 pixelsRow[x * 3 + 1] = 0;
241 pixelsRow[x * 3 + 2] = 0;
242 }
243 }
244
245 pixelsRow += width * 3;
246 maskPixelsRow += width;
247 }
248 }
249
250
251 int imageSize = imageProviderInfo.imageFormat.dimension.width *
252 imageProviderInfo.imageFormat.dimension.height *
253 imageProviderInfo.imageFormat.bytesPerPixel;
254 MetaInfoSizeBasePtr myMetaInfo = new MetaInfoSizeBase(
255 numResultImages * imageSize, numResultImages * imageSize, metaInfo->timeProvided);
256 provideResultImages(images, myMetaInfo);
257
258 ARMARX_VERBOSE << "CropRobotFromImage process finished";
259 }
260
268
269} // namespace armarx
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
#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)
Brief description of class CropRobotFromImage.
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.
static std::string GetDefaultName()
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.