ImageProcessor.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package VisionX::Core
19 * @author Kai Welke (kai dot welke at kit dot edu)
20 * @author Jan Issac (jan dot issac at gmx dot net)
21 * @date 2011
22 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
23 * GNU General Public License
24 */
25
26#pragma once
27
28// ArmarXCore
32#include <ArmarXCore/interface/core/SharedMemory.h>
33
34// IVT
35#include <Image/ByteImage.h>
36#include <Image/FloatImage.h>
37
38// VisionXInterfaces
39#include <VisionX/interface/core/DataTypes.h>
40#include <VisionX/interface/core/ImageProcessorInterface.h>
41
42// VisionXTools
43#include <condition_variable>
44#include <mutex>
45#include <shared_mutex>
46
49
50namespace visionx
51{
52 // forward declaration
56
57 /**
58 * @class ImageProcessorPropertyDefinitions
59 * @brief
60 */
62 {
63 public:
66 {
67 //defineRequiredProperty<std::string>("PropertyName", "Description");
69 "CompressionType",
70 eNoCompression,
71 "Compression algorithms to be used. Values: None, PNG, JPEG",
73 .setCaseInsensitive(false)
74 .map("None", eNoCompression)
75 .map("PNG", ePNG)
76 .map("JPEG", eJPEG)
77 .map("JPG", eJPEG);
79 "CompressionQuality",
80 95,
81 "Quality of the compression: PNG: 0-9 (9: best compression, but slowest), JPEG: "
82 "0-100 (100: best quality) ",
84 defineOptionalProperty<bool>("ForceIceTransfer",
85 false,
86 "If set to true, this image processor will always use the "
87 "Ice transfer for images instead of shared memory.");
88 }
89 };
90
91 /**
92 * The ImageProcessor class provides an interface for access to
93 * ImageProviders via Ice and shared memory. The interface defines a set of
94 * convenience methods which simplify the image access. ImageProcessor
95 * implements the ImageProcessorBase Ice interface for new image announcement
96 * and the armarx::ImageProvider providing visualizations.
97 */
98 class ImageProcessor : virtual public armarx::Component, virtual public ImageProcessorInterface
99 {
100 public:
101 static std::string ListenerSuffix;
102 std::string getImageListenerTopicName(std::string providerName) const;
103
104 protected:
105 /**
106 * Registers a delayed topic subscription and a delayed provider proxy
107 * retrieval which all will be available on the start of the component.
108 *
109 * @param name Provider name
110 */
111 void usingImageProvider(std::string name);
112 void releaseImageProvider(std::string providerName);
113
114 /**
115 * Select an ImageProvider.
116 *
117 * This method subscribes to an an ImageProvider and makes the provider
118 * available in the waitForImages() and getImages() methods.
119 *
120 * @param name Ice adapter name of the ImageProvider
121 * @param destinationImageType Image's type after image transmission
122 *
123 * @return Information of the image provider
124 */
125 ImageProviderInfo getImageProvider(std::string name,
126 ImageType destinationImageType = eRgb,
127 bool waitForProxy = false);
128 ImageProviderInfo getImageProvider(std::string name,
129 bool waitForProxy,
130 ImageType destinationImageType = eRgb);
131
132 /**
133 * Enables visualization
134 *
135 * @param numberImages number of images provided by the visualization
136 * @param imageDimension size of images
137 * @param imageType type of images
138 * @param name The topic name to use (if empty getName() + "Result" is used)
139 *
140 * @return Information of the image provider
141 */
142 void enableResultImages(int numberImages,
143 ImageDimension imageDimension,
144 ImageType imageType,
145 const std::string& name = "");
146
147 /**
148 * sends result images for visualization
149 * @see enableVisualization
150 *
151 * @param images array of images to send
152 */
153 void provideResultImages(CByteImage** images, armarx::MetaInfoSizeBasePtr info = nullptr);
154 void provideResultImages(const std::vector<CByteImageUPtr>& images,
155 armarx::MetaInfoSizeBasePtr info = nullptr);
156
157 /**
158 * Wait for new images.
159 *
160 * Wait for new image of an image provider. Use if only one
161 * ImageProvider is used (see useImageProvider).
162 *
163 * @param milliseconds Timeout for waiting
164 *
165 * @return True if new images are available. False in case of error or
166 * timeout
167 */
168 bool waitForImages(int milliseconds = 1000);
169
170 /**
171 * Wait for new images.
172 *
173 * Wait for new image of an image provider. Use if multiple
174 * ImageProviders are used (see useImageProvider).
175 *
176 * @param providerName Name of provider to wait for images
177 * @param milliseconds Timeout for waiting
178 *
179 * @return True if new images are available. False in case of error or
180 * timeout
181 */
182 bool waitForImages(std::string providerName, int milliseconds = 1000);
183
184 bool waitForImages(std::string providerName, IceUtil::Time waitTime);
185
186 bool isNewImageAvailable();
187 bool isNewImageAvailable(const std::string& providerName);
188
189 /**
190 * Poll images from provider.
191 *
192 * Polls images from a used ImageProvider either via shared memory or
193 * via Ice. If both components run on the same machine, shared memory
194 * transfer is used. Otherwise Ice is used for image transmission. The
195 * transfer type is decided in the useImageProvider method and is set
196 * in the corresponding ImageFormatInfo.
197 *
198 * Use this method if only one ImageProvider is used.
199 *
200 * @param ppImages Image buffers where the images are
201 * copied to. The buffers have to be
202 * initialized by the component. All
203 * required information for the allocation
204 * of the buffers can be found in the
205 * corresponding ImageFormatInfo.
206 *
207 * @return Number of images copied. Zero if no new images have been
208 * available.
209 */
210 int getImages(CByteImage** ppImages);
211
212 /**
213 * Poll images from provider.
214 *
215 * Polls images from a used ImageProvider either via shared memory or
216 * via Ice. If both components run on the same machine, shared memory
217 * transfer is used. Otherwise Ice is used for image transmission. The
218 * transfer type is decided in the useImageProvider method and is set
219 * in the corresponding ImageFormatInfo.
220 *
221 * Use this method if multiple ImageProviders are used.
222 *
223 * @param providerName Name of provider to poll from
224 *
225 * @param ppImages Image buffers where the images are
226 * copied to. The buffers have to be
227 * initialized by the component. All
228 * required information for the allocation
229 * of the buffers can be found in the
230 * corresponding ImageFormatInfo.
231 *
232 * @return Number of images copied. Zero if no new images have been
233 * available.
234 */
235 int getImages(std::string providerName,
236 CByteImage** ppImages,
237 armarx::MetaInfoSizeBasePtr& info);
238 int getImages(std::string providerName,
239 const std::vector<CByteImageUPtr>& ppImages,
240 armarx::MetaInfoSizeBasePtr& info);
241
242 /**
243 * @see ImageProcessorBase::getImages(CByteImage*)
244 */
245 int getImages(CFloatImage** ppImages);
246
247 /**
248 * @see ImageProcessorBase::getImages(std::string, CByteImage**)
249 */
250 int getImages(std::string providerName,
251 CFloatImage** ppImages,
252 armarx::MetaInfoSizeBasePtr& info);
253
254 /**
255 * Retrieve statistics for a connection to an ImageProvider.
256 *
257 * @param provideNname Name of the provider
258 * @param resetStats Reset statistics
259 *
260 * @return Reference to statistics for the connection to the provder
261 */
262 ImageTransferStats getImageTransferStats(std::string provideNname, bool resetStats = false);
263
264
265 /**
266 * @brief Get meta information from the image provider.
267 * @param imageProviderName Name of image provider. If empty, returns first entry in ImageProvider map.
268 * @return Null if no ImageProvider used or name could not be found.
269 */
270 armarx::MetaInfoSizeBasePtr
271 getImageMetaInfo(const std::string& imageProviderName = "") const;
272
273 void setFramerate(float fps);
274 float getFramerate() const;
275
276 /**
277 * Sets the compression type and compression quality. Quality needs to fit to compressionType: PNG: 0-9 (9: best compression, but slowest), JPEG: 0-100 (100: best quality) *
278 */
279 void setCompressionType(CompressionType compressionType = ePNG, int compressionQuality = 9);
280 CompressionType getCompressionType() const;
281 int getCompressionQuality() const;
282
283
284 // ================================================================== //
285 // == Interface of an ImageProcessor ================================ //
286 // ================================================================== //
287 /**
288 * Setup the vision component.
289 *
290 * Implement this method in the ImageProcessor in order to setup its
291 * parameters. Use this for the registration of adaptars and
292 * subscription to topics
293 *
294 * @param argc number of filtered command line arguments
295 * @param argv filtered command line arguments
296 */
297 virtual void onInitImageProcessor() = 0;
298
299 /**
300 * Implement this method in the ImageProcessor in order execute parts
301 * when the component is fully initialized and about to run.
302 */
303 virtual void onConnectImageProcessor() = 0;
304
305 /**
306 * Implement this method in the ImageProcessor in order execute parts
307 * when the component looses network connectivity.
308 */
309 virtual void
313
314 /**
315 * Exit the ImapeProcessor component.
316 *
317 * Implement this method in order to clean up the ImageProcessor
318 */
319 virtual void onExitImageProcessor() = 0;
320
321 /**
322 * Process the vision component.
323 *
324 * The main loop of the imageprocessor to be implemented in the
325 * subclass. Do not block this method. One process should execute
326 * exactly one image processing step.
327 * The rate at which this function is called can be set with setFramerate().
328 * If no framerate is set, the process will run as fast as possible.
329 * @see setFramerate
330 */
331 virtual void process() = 0;
332
333 // ================================================================== //
334 // == RunningComponent implementation =============================== //
335 // ================================================================== //
336 /**
337 * @see Component::onInitComponent()
338 */
339 void onInitComponent() override;
340
341 /**
342 * @see Component::onConnectComponent()
343 */
344 void onConnectComponent() override;
345
346 /**
347 * @see Component::onDisconnectComponent()
348 */
349 void onDisconnectComponent() override;
350
351 /**
352 * @see Component::onExitComponent()
353 */
354 void onExitComponent() override;
355
356 /**
357 * @see PropertyUser::createPropertyDefinitions()
358 */
360 void componentPropertiesUpdated(const std::set<std::string>& changedProperties) override;
361
362 protected:
363 /**
364 * @see PeriodicTask
365 */
366 virtual void runProcessor();
367
368 // ================================================================== //
369 // == SharedMemoryComponent Ice interface =========================== //
370 // ================================================================== //
371 /**
372 * Returns machines hardware Id string
373 */
374 std::string getHardwareId(const Ice::Current& c = Ice::emptyCurrent);
375
376 // ================================================================== //
377 // == ImageListener Ice interface =================================== //
378 // ================================================================== //
379 /**
380 * Listener callback function. This is called by the used image
381 * providers to report the availability of a newly captured
382 * image.
383 *
384 * @param providerName The reporting image provider name
385 */
386 void reportImageAvailable(const std::string& providerName,
387 const Ice::Current& c = Ice::emptyCurrent) override;
388
389 // ================================================================== //
390 // == ImageProcessor internals ====================================== //
391 // ================================================================== //
392 /**
393 * @see ImageProcessorBase::getImages(CByteImage**)
394 */
395 int getImages(void** ppBuffer);
396
397 /**
398 * @see ImageProcessorBase::getImages(std::string, CByteImage**)
399 */
400 int getImages(std::string providerName, void** ppBuffer, armarx::MetaInfoSizeBasePtr& info);
401
402 /**
403 * Returns the number of images provided by the specified image provider
404 * If no provider is specified, the first provider is taken.
405 *
406 * @param providerName Requested image provider
407 */
408 int getNumberOfImages(const std::string& providerName = "");
409
410 /**
411 * clean up memory
412 */
413 void cleanup();
414
415 // image provider
417 std::map<std::string, armarx::IceSharedMemoryConsumer<unsigned char>::pointer_type>;
419
420 std::map<std::string, ImageProviderInfo> imageProviderInfoMap;
421 std::shared_mutex imageProviderInfoMutex;
422
423 // result image visualization
425
426 // statistics
427 std::mutex statisticsMutex;
428 std::map<std::string, ImageTransferStats> statistics;
429
431
432 float desiredFps = 0;
434
435
436 CompressionType compressionType = eNoCompression;
438 };
439
440 /**
441 * Shared pointer for convenience
442 */
444
445 // ====================================================================== //
446 // == class ImageTransferStats declaration ============================== //
447 // ====================================================================== //
448
449 /**
450 * The ImageTransferStats class provides information on the connection
451 * between ImageProvider and ImageProcessor. Use
452 * ImageProcessorBase::getImageTransferStats() in order to retrieve the
453 * statistics
454 */
456 {
457 public:
459 {
460 imageProviderFPS.reset();
461 pollingFPS.reset();
462 }
463
464 /**
465 * Statistics for the images announced by the ImageProvider.
466 */
468
469 /**
470 * Statistics for the images polled by the ImageProcessor.
471 */
473 };
474
475 // ====================================================================== //
476 // == class ImageProviderInfo declaration =============================== //
477 // ====================================================================== //
478
480 {
481 public:
482 /**
483 * proxy to image provider
484 */
485 ImageProviderInterfacePrx proxy;
486
487 /**
488 * memory block
489 */
490 std::vector<unsigned char> buffer;
491
492 /**
493 * meta info
494 */
495 armarx::MetaInfoSizeBasePtr info;
496
497 /**
498 * Required image destination type.
499 *
500 * This is used to convert the transmitted image into an image with the
501 * desired image type if necessary, since the transmitted image type is
502 * given by the provider.
503 */
505
506 /**
507 * Image format struct that contains all necessary image information
508 */
509 ImageFormatInfo imageFormat;
510
511 /**
512 * Transfer mode of images
513 */
514 ImageTransferMode imageTransferMode;
515
516 /**
517 * Number of images.
518 */
520
521 /**
522 * Indicates whether an image is available.
523 */
525
526 /**
527 * Conditional variable used internally for synchronization purposes
528 */
529 std::shared_ptr<std::condition_variable> imageAvailableEvent;
530 };
531
532 // ====================================================================== //
533 // == class ResultImageProvider declaration ============================= //
534 // ====================================================================== //
535 /**
536 * The ResultImageProvider is used by the ImageProcessor to stream
537 * result images to any other processor (e.g. ImageMonitor)
538 * Use ImageProcessor::enableVisualization() and ImageProcessor::provideResultImages()
539 * in order to offer result images in an image processor.
540 */
542 {
543 friend class ImageProcessor;
544
545 public:
546 ResultImageProvider() : resultImageProviderName("ResultImageProvider")
547 {
548 }
549
550 void
552 {
553 this->numberResultImages = numberResultImages;
554 }
555
556 void
557 setResultImageFormat(ImageDimension resultImageDimension, ImageType resultImageType)
558 {
559 this->resultImageDimension = resultImageDimension;
560 this->resultImageType = resultImageType;
561 }
562
563 void
564 provideResultImages(CByteImage** images, Ice::Long timestamp)
565 {
567 provideImages(images, IceUtil::Time::microSeconds(timestamp));
568 }
569
570 void
571 provideResultImages(const std::vector<CByteImageUPtr>& images, Ice::Long timestamp)
572 {
574 provideImages(images, IceUtil::Time::microSeconds(timestamp));
575 }
576
577
578 protected:
579 void
580 setResultImageProviderName(const std::string& name)
581 {
582 this->resultImageProviderName = name;
583 }
584
585 std::string
586 getDefaultName() const override
587 {
588 return resultImageProviderName;
589 }
590
591 void
593 {
595 setImageFormat(resultImageDimension, resultImageType);
596 }
597
598 void
600 {
601 }
602
604
605 private:
606 std::string resultImageProviderName;
607
608 visionx::ImageDimension resultImageDimension;
609 visionx::ImageType resultImageType;
610 };
611
612} // namespace visionx
std::string timestamp()
constexpr T c
Default component property definition container.
Definition Component.h:70
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
Baseclass for all ArmarX ManagedIceObjects requiring properties.
Definition Component.h:94
void waitForProxy(std::string const &name, bool addToDependencies)
IceUtil::Handle< PeriodicTask< T > > pointer_type
Shared pointer type for convenience.
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
The FPSCounter class provides methods for calculating the frames per second (FPS) count in periodic t...
Definition FPSCounter.h:37
ImageProcessorPropertyDefinitions(std::string prefix)
The ImageProcessor class provides an interface for access to ImageProviders via Ice and shared memory...
void onInitComponent() override
IceInternal::Handle< ResultImageProvider > resultImageProvider
virtual void process()=0
Process the vision component.
std::string getHardwareId(const Ice::Current &c=Ice::emptyCurrent)
Returns machines hardware Id string.
void componentPropertiesUpdated(const std::set< std::string > &changedProperties) override
Implement this function if you would like to react to changes in the properties.
std::map< std::string, ImageProviderInfo > imageProviderInfoMap
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
int getImages(std::string providerName, const std::vector< CByteImageUPtr > &ppImages, armarx::MetaInfoSizeBasePtr &info)
armarx::PeriodicTask< ImageProcessor >::pointer_type processorTask
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
virtual void onInitImageProcessor()=0
Setup the vision component.
bool waitForImages(int milliseconds=1000)
Wait for new images.
virtual void onConnectImageProcessor()=0
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
void onDisconnectComponent() override
static std::string ListenerSuffix
int getImages(CByteImage **ppImages)
Poll images from provider.
void cleanup()
clean up memory
CompressionType compressionType
armarx::MetaInfoSizeBasePtr getImageMetaInfo(const std::string &imageProviderName="") const
Get meta information from the image provider.
CompressionType getCompressionType() const
virtual void onDisconnectImageProcessor()
Implement this method in the ImageProcessor in order execute parts when the component looses network ...
std::map< std::string, armarx::IceSharedMemoryConsumer< unsigned char >::pointer_type > ImageProviderMap
ImageTransferStats getImageTransferStats(std::string provideNname, bool resetStats=false)
Retrieve statistics for a connection to an ImageProvider.
void setCompressionType(CompressionType compressionType=ePNG, int compressionQuality=9)
Sets the compression type and compression quality.
int getNumberOfImages(const std::string &providerName="")
Returns the number of images provided by the specified image provider If no provider is specified,...
virtual void onExitImageProcessor()=0
Exit the ImapeProcessor component.
void onConnectComponent() override
void provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
std::map< std::string, ImageTransferStats > statistics
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void releaseImageProvider(std::string providerName)
void reportImageAvailable(const std::string &providerName, const Ice::Current &c=Ice::emptyCurrent) override
Listener callback function.
void provideResultImages(const std::vector< CByteImageUPtr > &images, armarx::MetaInfoSizeBasePtr info=nullptr)
void onExitComponent() override
std::string getImageListenerTopicName(std::string providerName) const
std::shared_mutex imageProviderInfoMutex
ImageProviderMap usedImageProviders
ImageType destinationImageType
Required image destination type.
bool imageAvailable
Indicates whether an image is available.
ImageTransferMode imageTransferMode
Transfer mode of images.
std::vector< unsigned char > buffer
memory block
int numberImages
Number of images.
armarx::MetaInfoSizeBasePtr info
meta info
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
ImageProviderInterfacePrx proxy
proxy to image provider
std::shared_ptr< std::condition_variable > imageAvailableEvent
Conditional variable used internally for synchronization purposes.
ImageProvider abstract class defines a component which provide images via ice or shared memory.
void updateTimestamp(Ice::Long timestamp, bool threadSafe=true)
Updates the timestamp of the currently captured image.
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
void provideImages(void **inputBuffers, const IceUtil::Time &imageTimestamp=IceUtil::Time())
send images raw.
void setNumberImages(int numberImages)
Sets the number of images on each capture.
The ImageTransferStats class provides information on the connection between ImageProvider and ImagePr...
FPSCounter pollingFPS
Statistics for the images polled by the ImageProcessor.
FPSCounter imageProviderFPS
Statistics for the images announced by the ImageProvider.
The ResultImageProvider is used by the ImageProcessor to stream result images to any other processor ...
void provideResultImages(CByteImage **images, Ice::Long timestamp)
void setResultImageProviderName(const std::string &name)
void provideResultImages(const std::vector< CByteImageUPtr > &images, Ice::Long timestamp)
void setResultImageFormat(ImageDimension resultImageDimension, ImageType resultImageType)
void onInitImageProvider() override
This is called when the Component::onInitComponent() is called.
void onExitImageProvider() override
This is called when the Component::onExitComponent() setup is called.
void setNumberResultImages(int numberResultImages)
std::string getDefaultName() const override
Retrieve default name of component.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
ArmarX headers.
IceInternal::Handle< ImageProcessor > ImageProcessorPtr
Shared pointer for convenience.