ImageSourceSelection.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::ImageSourceSelection
17  * @author Markus Grotz ( markus dot grotz at kit dot edu )
18  * @date 2016
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "ImageSourceSelection.h"
24 
25 
29 
32 
33 #include <Image/ImageProcessor.h>
34 
35 namespace armarx
36 {
37 
39  {
40  defaultProvider = getProperty<std::string>("defaultProviderName").getValue();
41  usingImageProvider(defaultProvider);
42 
44  }
45 
47  {
48  imageDisplayType = visionx::tools::typeNameToImageType("rgb");
49 
50  imageProviderInfo = getImageProvider(defaultProvider, imageDisplayType);
51  numImages = getProperty<int>("NumberOfImages").getValue() <= 0 ? imageProviderInfo.numberImages : getProperty<int>("NumberOfImages").getValue();
52  ARMARX_INFO << defaultProvider << " " << imageProviderInfo.imageFormat.dimension.width << "x" << imageProviderInfo.imageFormat.dimension.height;
53 
54  cameraImages[defaultProvider].resize(imageProviderInfo.numberImages);
55  for (int i = 0 ; i < imageProviderInfo.numberImages; i++)
56  {
57  cameraImages[defaultProvider].at(i).reset(visionx::tools::createByteImage(imageProviderInfo));
58  }
59 
60 
61  visionx::ImageDimension targetDimension = getProperty<visionx::ImageDimension>("TargetDimension").getValue();
62  visionx::ImageFormatInfo info;
63  info.bytesPerPixel = 3;
64  info.dimension = targetDimension;
65  info.type = imageDisplayType;
66  for (int i = 0; i < numImages; ++i)
67  {
68  resultCameraImages.push_back(visionx::CByteImageUPtr(visionx::tools::createByteImage(info, imageDisplayType)));
69  }
70 
71  if (numImages == 2)
72  {
73  enableStereoResultImages(targetDimension, imageDisplayType);
74  }
75  else
76  {
77  enableResultImages(numImages, targetDimension, imageDisplayType, getProperty<std::string>("resultProviderName"));
78  }
79 
80  setImageSource(defaultProvider);
81  }
82 
84  {
85  // for (int i = 0; i < numImages; i++)
86  // {
87  // delete cameraImages[i];
88  // }
89 
90  // delete [] cameraImages;
91 
92  // if (scaleFactorX > 0.0)
93  // {
94  // for (int i = 0; i < numImages; i++)
95  // {
96  // delete scaledCameraImages[i];
97  // }
98  // }
99  // delete [] scaledCameraImages;
100  }
101 
102  void ImageSourceSelection::deleteTimedOutProviders()
103  {
104  std::unique_lock lock(imageSourceMutex);
105 
106  std::map<std::string, int> deletionMap;
107  for (auto it = providerTimeouts.begin(); it != providerTimeouts.end(); it++)
108  {
109  deletionMap[it->first] = 0;
110  }
111  // delete providers that are timed out
112  for (auto it = providerTimeouts.begin(); it != providerTimeouts.end(); it++)
113  {
114  if (TimeUtil::GetTime() > it->second)
115  {
116 
117  if (it->first != defaultProvider)
118  {
119  deletionMap[it->first]++;
120  }
121  it = providerTimeouts.erase(it);
122 
123  }
124  else
125  {
126  deletionMap[it->first]--;
127  }
128 
129  }
130  for (auto& pair : deletionMap)
131  {
132  if (pair.second > 0)
133  {
134  ARMARX_INFO << "Deleting image source " << pair.first;
135  std::unique_lock lock(mutex);
136  releaseImageProvider(pair.first);
137  }
138  }
139  }
140 
142  {
143 
144  deleteTimedOutProviders();
145 
146  auto activeProvider = getCurrentImageSource();
147  std::unique_lock lock(mutex);
148  if (!usedImageProviders.count(activeProvider))
149  {
150  setImageSource(activeProvider);
151  }
152  if (!waitForImages(activeProvider))
153  {
154  ARMARX_INFO << deactivateSpam(30, activeProvider) << "Timeout while waiting for images from " << activeProvider;
155  return;
156  }
157  armarx::MetaInfoSizeBasePtr info;
158  ARMARX_DEBUG << deactivateSpam(5, activeProvider) << "Getting image from " << activeProvider << " width: " << cameraImages.at(activeProvider).at(0)->width;
159  if (getImages(activeProvider, cameraImages.at(activeProvider), info) < imageProviderInfoMap.at(activeProvider).numberImages)
160  {
161  ARMARX_WARNING << "Unable to transfer or read images";
162  return;
163  }
164 
165  auto currentNumberOfImages = std::min(numImages, imageProviderInfoMap.at(activeProvider).numberImages);
166  ARMARX_DEBUG << deactivateSpam(5, activeProvider) << VAROUT(currentNumberOfImages);
167 
168  visionx::ImageDimension targetDimension = getProperty<visionx::ImageDimension>("TargetDimension").getValue();
169  auto providerDimension = imageProviderInfoMap.at(activeProvider).imageFormat.dimension;
170  if (targetDimension != providerDimension && imageProviderInfo.imageFormat.type != imageDisplayType)
171  {
172  info->capacity = info->size = numImages * resultCameraImages[0]->bytesPerPixel * resultCameraImages[0]->width * resultCameraImages[0]->height;
173  ARMARX_DEBUG << deactivateSpam(30, activeProvider) << "Resizing and converting" << activeProvider;
174  for (int i = 0; i < currentNumberOfImages; i++)
175  {
176  auto otherTypeResizedImage = visionx::CByteImageUPtr(visionx::tools::createByteImage(imageProviderInfoMap.at(activeProvider)));
177  ::ImageProcessor::Resize(cameraImages.at(activeProvider).at(i).get(), otherTypeResizedImage.get());
178  ::ImageProcessor::ConvertImage(otherTypeResizedImage.get(), resultCameraImages.at(i).get());
179  }
180 
181  }
182  else if (targetDimension != providerDimension)
183  {
184  info->capacity = info->size = numImages * resultCameraImages[0]->bytesPerPixel * resultCameraImages[0]->width * resultCameraImages[0]->height;
185  for (int i = 0; i < currentNumberOfImages; i++)
186  {
187  ::ImageProcessor::Resize(cameraImages.at(activeProvider).at(i).get(), resultCameraImages.at(i).get());
188  }
189  provideResultImages(resultCameraImages, info);
190  }
191  else
192  {
193  ARMARX_DEBUG << deactivateSpam(5, activeProvider) << "No resizing";
194  // convert greyscale to rgb
195  if (imageProviderInfo.imageFormat.type != imageDisplayType)
196  {
197  for (int i = 0; i < currentNumberOfImages; i++)
198  {
199  ::ImageProcessor::ConvertImage(cameraImages.at(activeProvider).at(i).get(), resultCameraImages.at(i).get());
200  }
201  provideResultImages(resultCameraImages, info);
202  }
203  else
204  {
205  ARMARX_DEBUG << deactivateSpam(5, activeProvider) << "Same image type";
206  // copy since number of images might be different
207  for (int i = 0; i < currentNumberOfImages; i++)
208  {
209  ::ImageProcessor::CopyImage(cameraImages.at(activeProvider).at(i).get(), resultCameraImages.at(i).get());
210  }
211  provideResultImages(resultCameraImages, info);
212  }
213  }
214 
215 
216 
217 
218  }
219  void ImageSourceSelection::setImageSource(const std::string& imageSource, int relativeTimeoutMs, const Ice::Current& c)
220  {
221  ARMARX_CHECK_EXPRESSION(!imageSource.empty());
222  ARMARX_CHECK_GREATER(relativeTimeoutMs, 0);
223  std::unique_lock lock(imageSourceMutex);
224 
225  auto newTimeout = TimeUtil::GetTime() + IceUtil::Time::milliSeconds(relativeTimeoutMs);
226 
227 
228  if (!providerTimeouts.empty() && providerTimeouts.front().first == imageSource)
229  {
230  ARMARX_VERBOSE << "Refreshing timeout: " << newTimeout.toDateTime();
231  providerTimeouts.front().second = newTimeout;
232  }
233  else
234  {
235  ARMARX_VERBOSE << "inserting new imageprovider " << imageSource << " at front with timeout " << newTimeout.toDateTime();
236  providerTimeouts.insert(providerTimeouts.begin(), std::make_pair(imageSource, newTimeout));
237  }
238  // setImageSource(imageSource);
239  }
240 
241  void ImageSourceSelection::setImageSource(const std::string& imageSource)
242  {
243  std::unique_lock lock(mutex);
244  if (!usedImageProviders.count(imageSource))
245  {
246  addImageProvider(imageSource);
247  }
248  auto activeProvider = getCurrentImageSource();
249  if (imageSource != activeProvider)
250  {
251  ARMARX_INFO << "getting calibration for image provider " << imageSource;
252  visionx::StereoCalibrationInterfacePrx calibrationProvider = visionx::StereoCalibrationInterfacePrx::checkedCast(imageProviderInfoMap[imageSource].proxy);
253 
254  // activeProvider = imageSource.empty() ? defaultProvider : imageSource;
255 
256  if (calibrationProvider)
257  {
258 
259  visionx::StereoCalibration stereoCalibration = calibrationProvider->getStereoCalibration();
260 
261 
262  if (scaleFactorX)
263  {
264 
265  stereoCalibration.calibrationLeft.cameraParam.focalLength[0] /= scaleFactorX;
266  stereoCalibration.calibrationLeft.cameraParam.focalLength[1] /= scaleFactorX;
267 
268  stereoCalibration.calibrationLeft.cameraParam.principalPoint[0] /= scaleFactorX;
269  stereoCalibration.calibrationLeft.cameraParam.principalPoint[1] /= scaleFactorX;
270 
271  stereoCalibration.calibrationLeft.cameraParam.width /= scaleFactorX;
272  stereoCalibration.calibrationLeft.cameraParam.height /= scaleFactorX;
273 
274  stereoCalibration.calibrationRight.cameraParam.focalLength[0] /= scaleFactorX;
275  stereoCalibration.calibrationRight.cameraParam.focalLength[1] /= scaleFactorX;
276 
277 
278  stereoCalibration.calibrationRight.cameraParam.principalPoint[0] /= scaleFactorX;
279  stereoCalibration.calibrationRight.cameraParam.principalPoint[1] /= scaleFactorX;
280 
281 
282 
283  stereoCalibration.calibrationRight.cameraParam.width = ((float) stereoCalibration.calibrationRight.cameraParam.width) / scaleFactorX;
284  stereoCalibration.calibrationRight.cameraParam.height = ((float) stereoCalibration.calibrationRight.cameraParam.height) / scaleFactorX;
285 
286  }
287 
288 
289  StereoResultImageProviderPtr stereoResultImageProvider = StereoResultImageProviderPtr::dynamicCast(resultImageProvider);
290  if (stereoResultImageProvider)
291  {
292  stereoResultImageProvider->setStereoCalibration(stereoCalibration, calibrationProvider->getImagesAreUndistorted(), calibrationProvider->getReferenceFrame());
293  }
294 
295  }
296  }
297  }
298 
299  void ImageSourceSelection::removeImageSource(const std::string& imageSource)
300  {
301  for (auto it = providerTimeouts.begin(); it != providerTimeouts.end(); it++)
302  {
303  if (it->first == imageSource)
304  {
305  providerTimeouts.erase(it);
306  break;
307  }
308  }
309 
310  }
311 
312 
313  void ImageSourceSelection::enableStereoResultImages(visionx::ImageDimension imageDimension, visionx::ImageType imageType)
314  {
315  if (!resultImageProvider)
316  {
317  ARMARX_INFO << "Enabling StereoResultImageProvider";
318 
319  StereoResultImageProviderPtr stereoResultImageProvider = Component::create<StereoResultImageProvider>();
320  stereoResultImageProvider->setName(getProperty<std::string>("resultProviderName"));
322 
324 
325  resultImageProvider->setNumberResultImages(2);
326  resultImageProvider->setResultImageFormat(imageDimension, imageType);
327 
328  // wait for resultImageProvider
329  resultImageProvider->getObjectScheduler()->waitForObjectState(eManagedIceObjectStarted);
330  }
331  }
332 
333 
335  {
338  }
339 
340  bool ImageSourceSelection::addImageProvider(const std::string& providerName, visionx::ImageType imageDisplayType, visionx::ImageProviderInfo& imageProviderInfo)
341  {
342  bool result = true;
343 
344  visionx::ImageProviderInfo otherImageProviderInfo = getImageProvider(providerName, imageDisplayType);
345  ARMARX_INFO << providerName << " " << otherImageProviderInfo.imageFormat.dimension.width << "x" << otherImageProviderInfo.imageFormat.dimension.height;
346  cameraImages[providerName].resize(otherImageProviderInfo.numberImages);
347  for (int i = 0 ; i < otherImageProviderInfo.numberImages; i++)
348  {
349  cameraImages[providerName].at(i).reset(visionx::tools::createByteImage(otherImageProviderInfo));
350  }
351  visionx::StereoCalibrationInterfacePrx calibrationProvider = visionx::StereoCalibrationInterfacePrx::checkedCast(imageProviderInfo.proxy);
352  if (!calibrationProvider)
353  {
354  ARMARX_WARNING << "image provider does not have a stereo calibration interface";
355  }
356 
357 
358 
359  if (!result)
360  {
361  releaseImageProvider(providerName);
362  }
363  return result;
364  }
365 }
armarx::ImageSourceSelection::process
void process() override
Definition: ImageSourceSelection.cpp:141
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::ImageSourceSelection::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: ImageSourceSelection.cpp:334
visionx::ImageProviderInfo::numberImages
int numberImages
Number of images.
Definition: ImageProcessor.h:506
armarx::ImageSourceSelection::removeImageSource
void removeImageSource(const std::string &imageSource)
Definition: ImageSourceSelection.cpp:299
ArmarXManager.h
armarx::ImageSourceSelection::onInitImageProcessor
void onInitImageProcessor() override
Definition: ImageSourceSelection.cpp:38
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
visionx::ImageProcessor::getImageProvider
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
Definition: ImageProcessor.cpp:152
ARMARX_CHECK_GREATER
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
Definition: ExpressionException.h:116
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
ImageSourceSelection.h
visionx::ImageProviderInfo::imageFormat
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
Definition: ImageProcessor.h:496
visionx::tools::createByteImage
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
armarx::ImageSourceSelection::setImageSource
void setImageSource(const std::string &imageSource, int relativeTimeoutMs, const Ice::Current &c) override
Definition: ImageSourceSelection.cpp:219
visionx::ImageProviderInfo
Definition: ImageProcessor.h:466
armarx::ImageSourceSelection::getCurrentImageSource
std::string getCurrentImageSource(const Ice::Current &c=Ice::emptyCurrent) override
Definition: ImageSourceSelection.h:110
IceInternal::Handle
Definition: forward_declarations.h:8
visionx::CByteImageUPtr
std::unique_ptr< CByteImage > CByteImageUPtr
Definition: ImageProvider.h:57
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::ImageSourceSelection::onConnectImageProcessor
void onConnectImageProcessor() override
Definition: ImageSourceSelection.cpp:46
armarx::ImageSourceSelection::enableStereoResultImages
void enableStereoResultImages(visionx::ImageDimension imageDimension, visionx::ImageType imageType)
enable stereo result images
Definition: ImageSourceSelection.cpp:313
armarx::ImageSourceSelection::onExitImageProcessor
void onExitImageProcessor() override
Definition: ImageSourceSelection.cpp:83
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
ArmarXObjectScheduler.h
visionx::ImageProcessor::imageProviderInfoMap
std::map< std::string, ImageProviderInfo > imageProviderInfoMap
Definition: ImageProcessor.h:403
visionx::ImageProcessor::getImages
int getImages(CByteImage **ppImages)
Poll images from provider.
Definition: ImageProcessor.cpp:351
armarx::ImageSourceSelectionPropertyDefinitions
Definition: ImageSourceSelection.h:54
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
ExpressionException.h
armarx::ManagedIceObject::usingTopic
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Definition: ManagedIceObject.cpp:248
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
visionx::ImageProviderInfo::proxy
ImageProviderInterfacePrx proxy
proxy to image provider
Definition: ImageProcessor.h:472
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
float
#define float
Definition: 16_Level.h:22
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
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
ImageUtil.h
visionx::ImageProcessor::provideResultImages
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
Definition: ImageProcessor.cpp:245
armarx::ImageSourceSelection::addImageProvider
bool addImageProvider(const std::string &providerName)
Definition: ImageSourceSelection.h:149
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
visionx::ImageProcessor::usedImageProviders
ImageProviderMap usedImageProviders
Definition: ImageProcessor.h:401
TypeMapping.h
visionx::ImageProcessor::releaseImageProvider
void releaseImageProvider(std::string providerName)
Definition: ImageProcessor.cpp:137
min
T min(T t1, T t2)
Definition: gdiam.h:42
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
visionx::ImageProcessor::resultImageProvider
IceInternal::Handle< ResultImageProvider > resultImageProvider
Definition: ImageProcessor.h:407
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