SimpleEpisodicMemoryImageConnector.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::SimpleEpisodicMemoryImageConnector
17 * @author Fabian Peller ( fabian dot peller-konrad at kit dot edu )
18 * @date 2020
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25
26// STD/STL
27
28// IVT
29#include <Image/ImageProcessor.h>
30
31// ArmarX
32
33using namespace visionx;
34
41
42void
44{
45 ARMARX_DEBUG << "Initializing SimpleEpisodicMemoryImageConnector";
46
47 m_image_provider_id = getProperty<std::string>("ImageProviderName").getValue();
48 m_image_provider_channel = getProperty<unsigned int>("ImageProviderChannel");
49 ARMARX_VERBOSE << "Using image provider with ID '" << m_image_provider_id << "'.";
50
51 usingImageProvider(m_image_provider_id);
52 usingProxy("SimpleEpisodicMemory");
53
54 m_image_received = false;
55
56 setFramerate(1);
57}
58
59void
61{
62 // Get SimpleEpisodicMemory
64
65 // Connect to image provider.
66 m_image_provider_info = getImageProvider(m_image_provider_id);
67 m_image_provider = getProxy<visionx::ImageProviderInterfacePrx>(m_image_provider_id);
68
69 // Init input image.
70 num_of_received_images = static_cast<unsigned int>(m_image_provider_info.numberImages);
71 m_input_image_buf = new ::CByteImage*[num_of_received_images];
72 for (unsigned int i = 0; i < num_of_received_images; ++i)
73 {
74 m_input_image_buf[i] = visionx::tools::createByteImage(m_image_provider_info);
75 }
76 m_input_image = visionx::tools::createByteImage(m_image_provider_info);
77
78 // Kick off running task
80 this, &SimpleEpisodicMemoryImageConnector::checkForNewImages, m_periodic_task_interval);
81 m_periodic_task->start();
82}
83
84void
86{
87 // Stop task.
88 {
89 m_periodic_task->stop();
90 }
91
92 // Clear input image buffer.
93 {
94 for (unsigned int i = 0; i < num_of_received_images; ++i)
95 {
96 delete m_input_image_buf[i];
97 }
98 delete[] m_input_image_buf;
99 }
100}
101
102void
106
107void
109{
110 const IceUtil::Time timeout = IceUtil::Time::milliSeconds(1000);
111 if (!waitForImages(m_image_provider_id, static_cast<int>(timeout.toMilliSeconds())))
112 {
113 ARMARX_WARNING << "Timeout while waiting for camera images (>" << timeout << ")";
114 return;
115 }
116
117 ARMARX_DEBUG << "Received a new image. Putting image to member variable";
118 std::lock_guard<std::mutex> lock{m_input_image_mutex};
119
120 int num_images = getImages(m_image_provider_id, m_input_image_buf, m_image_meta_info);
121 m_timestamp_last_image = IceUtil::Time::microSeconds(m_image_meta_info->timeProvided);
122
123 if (static_cast<unsigned int>(num_images) != num_of_received_images)
124 {
125 // ERROR
126 }
127 else
128 {
129 // Only consider channel image.
130 ::ImageProcessor::CopyImage(m_input_image_buf[m_image_provider_channel], m_input_image);
131 m_image_received = true;
132 }
133 ARMARX_DEBUG << "Wait for next image";
134}
135
136void
137visionx::SimpleEpisodicMemoryImageConnector::checkForNewImages()
138{
139
140 if (!m_image_received)
141 {
142 return;
143 }
144
146 << "Got a new image for processing. Send image to EpisodicMemory. Image information: Size: "
147 << m_input_image->width << ", " << m_input_image->height << ", "
148 << m_input_image->bytesPerPixel;
149 std::lock_guard<std::mutex> lock{m_input_image_mutex};
150 m_image_received = false;
151
152 // TODO convert2Blob and enable png compression
153
154 memoryx::ImageEvent memory_image_event;
155 memory_image_event.providerName =
156 m_image_provider_id + "__" + std::to_string(m_image_provider_channel);
157 memory_image_event.receivedInMs = m_timestamp_last_image.toMilliSecondsDouble();
158 memory_image_event.height = m_input_image->height;
159 memory_image_event.width = m_input_image->width;
160 memory_image_event.colourType =
161 (m_input_image->bytesPerPixel == 3 ? memoryx::ColourSpace::RGB
162 : memoryx::ColourSpace::GRAYSCALE);
163 memory_image_event.data = std::vector<unsigned char>(
164 m_input_image->pixels,
165 m_input_image->pixels +
166 (m_input_image->height * m_input_image->width * m_input_image->bytesPerPixel));
167 m_simple_episodic_memory->registerImageEvent(memory_image_event);
168
169 ARMARX_DEBUG << deactivateSpam(0.5) << "Processed a new image";
170}
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
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)
The periodic task executes one thread method repeatedly using the time period specified in the constr...
memoryx::SimpleEpisodicMemoryInterface::ProxyType m_simple_episodic_memory
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.
int getImages(CByteImage **ppImages)
Poll images from provider.
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.
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 ...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#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
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
ArmarX headers.