iCub-main
Loading...
Searching...
No Matches
imageSplitter.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Istituto Italiano di Tecnologia - iCub Facility
2// Author: Alberto Cardellino <alberto.cardellino@iit.it>
3// CopyPolicy: Released under the terms of the GNU GPL v2.0.
4
5#include <yarp/os/Os.h>
6#include <yarp/os/Time.h>
7#include <yarp/os/LogStream.h>
8
9#include <imageSplitter.h>
10
11using namespace std;
12using namespace yarp::os;
13using namespace yarp::sig;
14
16{
17 horizontal = true;
18 method = 2;
19}
20
22{
23 horizontal = true;
24 method = 2;
25}
26
27bool ImageSplitter::configure(yarp::os::ResourceFinder &rf)
28{
29 bool shouldConnect =false;
30 if(rf.check("help"))
31 {
32 cout<<"Usage:"<<endl<<"<imageSplitter> --param1 arg1 --param2 arg2 ..."<<endl;
33 cout<<"Here the available parameters:"<<endl;
34 cout<<"align specify if the alignement of the images is 'vertical' or 'horizontal'"<<endl;
35 cout<<"local prefix for the ports that will be opened by this module, if not specified the default is '/imageSplitter'"<<endl;
36 cout<<"nameInput name of the module's' input port, if not specified by default is <local> + '/input:i'"<<endl;
37 cout<<"nameLeft name of the output port for the 'left image', if not specified by default is <local> + '/left:o'"<<endl;
38 cout<<"nameRight name of the output port for the 'right image', if not specified by default is <local> + '/right:o'"<<endl;
39 cout<<"remote name of the source port, if specified it connects automatically to the module's input port"<<endl;
40 std::exit(1);
41 }
42 // Check input parameters
43 if(rf.check("align"))
44 {
45 string align = rf.find("align").asString();
46 if(align == "vertical")
47 {
48 horizontal = false;
49 }
50 else if(align == "horizontal")
51 {
52 horizontal = true;
53 }
54 else
55 {
56 yError() << " Incorrect parameter. Supported values for alignment are 'horizontal' or 'vertical'";
57 return false;
58 }
59 }
60 string inputPortName;
61 string outLeftPortName;
62 string outRightPortName;
63
64
65 if(rf.check("local"))
66 {
67 string rootName = rf.find("local").asString();
68 inputPortName = rootName + "/input:i";
69 outLeftPortName = rootName + "/left:o";
70 outRightPortName = rootName + "/right:o";
71 }
72 else{
73 inputPortName = "/imageSplitter/input:i";
74 outLeftPortName = "/imageSplitter/left:o";
75 outRightPortName = "/imageSplitter/right:o";
76 }
77 if (rf.check("nameInput"))
78 {
79 inputPortName = rf.find("nameInput").asString();
80 }
81
82 if(rf.check("nameLeft"))
83 {
84 outLeftPortName = rf.find("nameLeft").asString();
85 }
86
87 if(rf.check("nameRight"))
88 {
89 outRightPortName = rf.find("nameRight").asString();
90 }
91
92 // opening ports
93 bool ret=true;
94 ret &= inputPort.open(inputPortName);
95 ret &= outLeftPort.open(outLeftPortName);
96 ret &= outRightPort.open(outRightPortName);
97
98 string remotePortName;
99
100 if(rf.check("remote"))
101 {
102 remotePortName = rf.find("remote").asString();
103 shouldConnect = true;
104
105 }
106 else
107 yInfo() << "ImageSplitter: waiting for connection to port" << inputPortName;
108
109 if(!ret)
110 {
111 yError() << " Cannot open ports";
112 return false;
113 }
114
115 // Connections
116 if (shouldConnect){
117 yInfo("connecting to the source...\n");
118 if(! yarp::os::Network::connect(remotePortName, inputPortName))
119 {
120 yError() << "Cannot connect to remote port " << remotePortName;
121 return false;
122 }
123 }
124
125 // choose filling method
126 if(rf.check("m"))
127 {
128 string align = rf.find("m").asString();
129 if(align == "pixel")
130 {
131 method = 0;
132 }
133 else if(align == "pixel2")
134 {
135 method = 1;
136 }
137 else if(align == "line")
138 {
139 method = 2;
140 }
141 else if(align == "whole")
142 {
143 if(horizontal)
144 yError() << "Cannot use 'whole' method for input image horizontally aligned";
145 method = 3;
146 }
147 else
148 {
149 yError() << "Methods are pixel, line, whole; got " << align;
150 return false;
151 }
152 }
153
154 yInfo() << "using method " << method;
155 return true;
156}
157
159{
160
161 return true;
162}
163
165{
166 return true;
167}
168
170{
171 ImageOf<PixelRgb> *inputImage = inputPort.read();
172 yarp::os::Stamp stamp;
173 inputPort.getEnvelope(stamp);
174
175 ImageOf<PixelRgb> &outLeftImage = outLeftPort.prepare();
176 ImageOf<PixelRgb> &outRightImage = outRightPort.prepare();
177
178 inWidth = inputImage->width();
179 inHeight = inputImage->height();
180
181 if(horizontal) // input image is horizontally aligned
182 {
183 outWidth = inWidth/2;
184 outHeight = inHeight;
185 }
186 else
187 {
188 outWidth = inWidth;
189 outHeight = inHeight/2;
190 }
191
192 outLeftImage.setQuantum(inputImage->getQuantum());
193 outRightImage.setQuantum(inputImage->getQuantum());
194 outLeftImage.resize(outWidth, outHeight);
195 outRightImage.resize(outWidth, outHeight);
196
197 // alloc and compute some vars for efficency
198 int h2, w2;
199 unsigned char *pixelLeft, *pixelRight;
200 unsigned char *pixelInputL, *pixelInputR;
201 unsigned char *pixelInput = inputImage->getRawImage();
202 int dualImage_rowSizeByte = inputImage->getRowSize();
203 int singleImage_rowSizeByte = outLeftImage.getRowSize();
204 int singleImage_wholeSizeByte = outWidth * outHeight * outLeftImage.getPixelSize();
205
206 static int counter = 0;
207 static double start = 0;
208 start = yarp::os::Time::now();
209
210 switch(method)
211 {
212 case 0: // pixel by pixel
213 {
214 if(horizontal)
215 {
216 for(int h=0; h<outHeight; h++)
217 {
218 for(int w1=0; w1<outWidth; w1++)
219 {
220 w2 = w1+outWidth;
221 pixelLeft = outLeftImage.getPixelAddress(w1, h);
222 pixelLeft[0] = *(inputImage->getPixelAddress(w1, h)+0);
223 pixelLeft[1] = *(inputImage->getPixelAddress(w1, h)+1);
224 pixelLeft[2] = *(inputImage->getPixelAddress(w1, h)+2);
225
226 pixelRight = outRightImage.getPixelAddress(w1, h);
227 pixelRight[0] = *(inputImage->getPixelAddress(w2, h)+0);
228 pixelRight[1] = *(inputImage->getPixelAddress(w2, h)+1);
229 pixelRight[2] = *(inputImage->getPixelAddress(w2, h)+2);
230 }
231 }
232 }
233 else
234 {
235 for(int h1=0; h1<outHeight; h1++)
236 {
237 for(int w=0; w<outWidth; w++)
238 {
239 h2 = h1+outHeight;
240 pixelLeft = outLeftImage.getPixelAddress(w, h1);
241 pixelLeft[0] = *(inputImage->getPixelAddress(w, h1)+0);
242 pixelLeft[1] = *(inputImage->getPixelAddress(w, h1)+1);
243 pixelLeft[2] = *(inputImage->getPixelAddress(w, h1)+2);
244
245 pixelRight = outRightImage.getPixelAddress(w, h1);
246 pixelRight[0] = *(inputImage->getPixelAddress(w, h2)+0);
247 pixelRight[1] = *(inputImage->getPixelAddress(w, h2)+1);
248 pixelRight[2] = *(inputImage->getPixelAddress(w, h2)+2);
249 }
250 }
251 }
252 } break;
253
254 case 1: // pixel by pixel, a bit better
255 {
256 if(horizontal)
257 {
258 pixelLeft = outLeftImage.getRawImage();
259 pixelRight = outRightImage.getRawImage();
260
261 pixelInputL = pixelInput;
262 pixelInputR = pixelInput+singleImage_rowSizeByte;
263 for(int h=0, idx=0, idx2=0; h<outHeight; h++)
264 {
265 for(int w=0; w<outWidth; w++)
266 {
267 pixelLeft[idx++] = *(pixelInputL++);
268 pixelLeft[idx++] = *(pixelInputL++);
269 pixelLeft[idx++] = *(pixelInputL++);
270
271 pixelRight[idx2++] = *(pixelInputR++);
272 pixelRight[idx2++] = *(pixelInputR++);
273 pixelRight[idx2++] = *(pixelInputR++);
274 }
275 pixelInputL += singleImage_rowSizeByte;
276 pixelInputR += singleImage_rowSizeByte;
277 }
278 }
279 else
280 {
281
282 }
283 } break;
284
285 case 2: // line by line
286 {
287 if(horizontal)
288 {
289 pixelLeft = outLeftImage.getRawImage();
290 pixelRight = outRightImage.getRawImage();
291
292 for(int h=0; h<inHeight; h++)
293 {
294 memcpy(pixelLeft + h*singleImage_rowSizeByte, pixelInput, singleImage_rowSizeByte);
295 memcpy(pixelRight + h*singleImage_rowSizeByte, pixelInput+=singleImage_rowSizeByte, singleImage_rowSizeByte);
296 pixelInput+= dualImage_rowSizeByte/2;
297 }
298 }
299 else
300 {
301 pixelLeft = outLeftImage.getRawImage();
302 pixelRight = outRightImage.getRawImage();
303 pixelInputL = pixelInput;
304 pixelInputR = pixelInput+singleImage_wholeSizeByte;
305
306 for(int h=0; h<outHeight; h++)
307 {
308 memcpy(pixelLeft + h*singleImage_rowSizeByte, pixelInputL, singleImage_rowSizeByte);
309 memcpy(pixelRight + h*singleImage_rowSizeByte, pixelInputR, singleImage_rowSizeByte);
310 pixelInputL+= singleImage_rowSizeByte;
311 pixelInputR+= singleImage_rowSizeByte;
312 }
313 }
314 } break;
315
316 case 3: // whole image, only if input image is vertically aligned
317 {
318 if(horizontal)
319 {
320 yError() << "Cannot use this copy method with horizontally aligned source image.";
321 }
322 else
323 {
324 pixelLeft = outLeftImage.getRawImage();
325 pixelRight = outRightImage.getRawImage();
326
327 memcpy(pixelLeft, pixelInput, singleImage_wholeSizeByte);
328 memcpy(pixelRight, pixelInput+ singleImage_wholeSizeByte, singleImage_wholeSizeByte);
329 }
330 } break;
331
332 default:
333 {
334 yError() << " @line " << __LINE__ << "unhandled switch case, we should not be here!";
335 }
336 }
337
338 static double end = 0;
339 static double elapsed = 0;
340 end = yarp::os::Time::now();
341 elapsed += (end-start);
342
343 counter++;
344 if((counter % 100) == 0)
345 {
346 yInfo() << "Elapsed time: " << elapsed;
347 elapsed = 0;
348 }
349
350 outLeftPort.setEnvelope(stamp);
351 outRightPort.setEnvelope(stamp);
352
353 outLeftPort.write();
354 outRightPort.write();
355 return true;
356}
357
358
360{
361 return 0.01;
362}
363
bool configure(yarp::os::ResourceFinder &rf)
static uint32_t idx[BOARD_NUM]