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