iCub-main
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 
11 using namespace std;
12 using namespace yarp::os;
13 using namespace yarp::sig;
14 
16 {
17  horizontal = true;
18  method = 2;
19 }
20 
22 {
23  horizontal = true;
24  method = 2;
25 }
26 
27 bool 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)
double getPeriod()
bool interruptModule()
static uint32_t idx[BOARD_NUM]