contour.cpp
Go to the documentation of this file.
1 
10 #include "tuw_utils/contour.h"
11 #include <iostream>
12 #include <stack>
13 #include <cstdio>
14 
15 namespace tuw {
16 
17 const int Contour::ANGLE_8U = 8;
18 const int Contour::ANGLE_32F = 32;
19 const int Contour::ANGLE_64F = 64;
20 
21 
22 const int Contour::MODE_SIMPLE = 1;
23 const int Contour::MODE_CONTOUR = 2;
24 const int Contour::MODE_GRAIDENT = 3;
25 const int Contour::MODE_COMPLEX = 4;
26 
27 const float Contour::fPi = 3.1415926535897932384626433832795;
28 const double Contour::dPi = 3.1415926535897932384626433832795;
29 
30 const int Contour::pppDirectionWeightsField[4][3][3] = {
31  { {2,1,2}, // 0 0 0
32  {4,0,4}, // 1 1 1
33  {2,1,2} // 0 0 0
34  },
35  { {1,2,4}, // 0 0 1
36  {2,0,2}, // 0 1 0
37  {4,2,1} // 1 0 0
38  },
39  { {2,4,2}, // 0 1 0
40  {1,0,1}, // 0 1 0
41  {2,4,4} // 0 1 0
42  },
43  { {4,2,1}, // 1 0 0
44  {2,0,2}, // 0 1 0
45  {1,2,4} // 0 0 1
46  }
47 };
48 
49 const int Contour::ppGradientWeightsField[4][9] = {
50  {3, 5, 6, 8, 2, 0, 7, 1, 4},
51  {2, 6, 1, 3, 7, 5, 0, 8, 4},
52  {1, 7, 0, 6, 8, 2, 3, 5, 4},
53  {0, 8, 1, 7, 5, 3, 2, 6, 4}
54 };
55 
56 const int Contour::pppCommingFromEdgeWeightsField[9][3][3] = {
57  { {0,1,2}, // 1 0 0
58  {1,0,3}, // 0 0 0
59  {2,3,4} // 0 0 0
60  },
61  { {1,0,1}, // 0 1 0
62  {2,0,2}, // 0 0 0
63  {3,4,3} // 0 0 0
64  },
65  { {2,1,0}, // 0 0 1
66  {3,0,1}, // 0 0 0
67  {4,3,2} // 0 0 0
68  },
69  { {1,2,3}, // 0 0 0
70  {0,0,4}, // 1 0 0
71  {1,2,3} // 0 0 0
72  },
73  { {0,0,0}, // 0 0 0
74  {0,0,0}, // 0 1 0
75  {0,0,0} // 0 0 0
76  },
77  { {3,2,1}, // 0 0 0
78  {4,0,0}, // 0 0 1
79  {3,2,1} // 0 0 0
80  },
81  { {2,3,4}, // 0 0 0
82  {1,0,3}, // 0 0 0
83  {0,1,2} // 1 0 0
84  },
85  { {3,4,3}, // 0 0 0
86  {2,0,2}, // 0 0 0
87  {1,0,1} // 0 1 0
88  },
89  { {4,3,2}, // 0 0 0
90  {3,0,1}, // 0 0 0
91  {2,1,0} // 0 0 1
92  }
93 };
94 
95 const int Contour::ppContourWeightsField[9][9] = {
96  {8, 7, 5, 6, 2, 3, 1, 0, 4},
97  {7, 6, 8, 3, 5, 0, 2, 1, 4},
98  {6, 7, 3, 8, 0, 5, 1, 2, 4},
99  {5, 2, 8, 1, 7, 0, 6, 3, 4},
100  {0, 0, 0, 0, 0, 0, 0, 0, 0},
101  {3, 6, 0, 7, 1, 8, 2, 5, 4},
102  {2, 1, 5, 0, 8, 3, 7, 6, 4},
103  {1, 2, 0, 3, 5, 6, 8, 7, 4},
104  {0, 1, 3, 2, 6, 5, 7, 8, 4}
105 };
106 
108  mpImgEdge ( NULL ),
109  mpImgEdgeDirection ( NULL ),
110  mdImgEdgeDirectionType ( 0 ),
111  mdefEdgeLinkMode ( 0 ),
112  mImgWidth ( 0 ),
113  mImgHeight ( 0 ),
114  mbAllowToModifyTheSources ( false ),
115 // mpEdges ( NULL ),
116  mNrOfEdges ( 0 ) {}
117 
120 }
121 
123  RelaseMemory();
124  if ( mbAllowToModifyTheSources == false ) {
125  mpImgEdge = ( unsigned char* ) malloc ( sizeof ( unsigned char ) * mImgWidth * mImgHeight );
126  }
127  //mpEdges = ( CvPoint* ) malloc ( sizeof ( CvPoint ) * mImgWidth * mImgHeight );
128  mEdges.resize ( mImgWidth * mImgHeight );
129  mAngle8Bit.resize ( mImgWidth * mImgHeight );
130 }
131 
134  if ( mpImgEdge != NULL ) {
135  free ( mpImgEdge );
136  mpImgEdge = NULL;
137  }
138  /*
139  if ( mpEdges != NULL ) {
140  free ( mpEdges );
141  mpEdges = NULL;
142  }
143  */
144  }
145 }
146 
147 int Contour::getContours( std::vector<std::vector<cv::Point> > &contours, unsigned int min_length) {
148  contours.clear();
149  std::vector<cv::Range> idx = getSegmentIndexes () ;
150  for ( unsigned int i = 0; i < idx.size(); i++ ) {
151  int length = idx[i].end - idx[i].start;
152  if (length > min_length) {
153  contours.push_back(std::vector<cv::Point>());
154  for ( int index = idx[i].start; index < idx[i].end; index++ ) {
155  CvPoint &edge = (mEdges)[index];
156  contours.back().push_back( edge);
157  }
158  }
159  }
160  return contours.size();
161 }
162 
163 void Contour::Draw( unsigned char* pImgRGB ) {
164  unsigned char *pDes;
165  std::vector<cv::Range> idx = getSegmentIndexes () ;
166  for ( unsigned int i = 0; i < idx.size(); i++ ) {
167  unsigned char pColor[] = {rand() / ( RAND_MAX/0xFF ), rand() / ( RAND_MAX/0xFF ), rand() / ( RAND_MAX/0xFF ) };
168  for ( int index = idx[i].start; index < idx[i].end; index++ ) {
169  CvPoint edge = (mEdges)[index];
170  pDes = pImgRGB + ( 3 * ( mImgWidth * edge.y + edge.x ) );
171  for ( int j = 0; j < 3; j++ ) {
172  pDes[j] = pColor[j];
173  }
174  }
175  }
176 }
177 
178 void Contour::Init ( unsigned int iImgWidth, unsigned int iImgHeight, bool bAllowToModifyTheSources, unsigned char iEdgeToProcess, unsigned char iEdgeInProcess, unsigned char iEdgeProcessed, unsigned char iEdgeStrengthRemoved ) {
179  if((iImgWidth != mImgWidth) || (mImgHeight != iImgHeight) ||
180  (mbAllowToModifyTheSources != bAllowToModifyTheSources) || (mEdgeToProcess != iEdgeToProcess) ||
181  (mEdgeInProcess != iEdgeInProcess) || (mEdgeProcessed != iEdgeProcessed)) {
182  RelaseMemory();
183  mImgWidth = iImgWidth;
184  mImgHeight = iImgHeight;
185  mbAllowToModifyTheSources = bAllowToModifyTheSources;
186  mEdgeToProcess = iEdgeToProcess;
187  mEdgeInProcess = iEdgeInProcess;
188  mEdgeProcessed = iEdgeProcessed;
189  AllocateMemory();
190  }
191 }
192 
193 int Contour::GetImgDirectionIndex ( CvPoint tPoint ) {
194  /* Direction of the change
195  1 0 3
196  * * *
197  * * *
198  2*******2
199  * * *
200  * * *
201  3 0 1
202  */
203  int iIndex = 0;
204  unsigned char i8BitAngle;
205  float fAngle;
206  double dAngle;
207  switch ( mdImgEdgeDirectionType ) {
208  case ANGLE_8U:
209  i8BitAngle = ( ( unsigned char* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
210  if ( i8BitAngle > 128 ) {
211  i8BitAngle -= 128;
212  }
213  i8BitAngle = i8BitAngle + 16;
214  iIndex = i8BitAngle / 32;
215  break;
216  case ANGLE_32F:
217  fAngle = ( ( float* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
218  if ( fAngle < 0 ) {
219  fAngle += fPi;
220  }
221  iIndex = ( int ) ( ( fAngle + fPi/8 ) * 3/fPi );
222  break;
223  case ANGLE_64F:
224  dAngle = ( ( double* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
225 
226  if ( dAngle < 0 ) {
227  dAngle += dPi;
228  }
229  iIndex = ( int ) ( ( dAngle + dPi/8 ) * 3/dPi );
230  break;
231  }
232  return iIndex;
233 }
234 
235 void Contour::Perform ( unsigned char* pImgEdgeStrength, int defEdgeLinkMode, void* pImgEdgeDirection, int dImgEdgeDirectionType ) {
236  mNrOfEdges = 0;
237  mSegments.clear();
238  mSegments.reserve ( 100 );
239  mdefEdgeLinkMode = defEdgeLinkMode;
240  mpImgEdgeDirection = pImgEdgeDirection;
241  mdImgEdgeDirectionType = dImgEdgeDirectionType;
243  mpImgEdge = pImgEdgeStrength;
244  } else {
245  memcpy ( mpImgEdge, pImgEdgeStrength, mImgWidth * mImgHeight );
246  }
247 
248  switch ( mdefEdgeLinkMode ) {
249  case MODE_SIMPLE:
250  Linking_Simple();
251  break;
252  case MODE_CONTOUR:
253  Linking_Contour();
254  break;
255  case MODE_GRAIDENT:
256  if ( pImgEdgeDirection == NULL ) {
257  printf ( "The linker mode requires an edge direction image!\n" );
258  }
260  break;
261  case MODE_COMPLEX:
262  if ( pImgEdgeDirection == NULL ) {
263  printf ( "The linker mode requires an edge direction image!\n" );
264  }
265  Linking_Complex();
266  break;
267  }
268 }
269 
270 
272  CvPoint tPoint = cvPoint(0,0);
273  cv::Range range(0,0);
274  for ( tPoint.y = 1; tPoint.y < mImgHeight-1; tPoint.y++ ) {
275  tPoint.x = 1;
276  unsigned char *pCurrent = getImgEdge ( tPoint );
277  for ( ; tPoint.x < mImgWidth-1; tPoint.x++ ) {
278  if ( *pCurrent >= mEdgeToProcess ) {
279  range.start = mNrOfEdges;
280  Trace_Simple ( tPoint, &range.end );
281  mSegments.push_back ( range );
282  //*pCurrent = 0;
283  }
284  pCurrent++;
285  }
286  }
287 }
288 
289 // void Contour::Trace_Simple ( CvPoint tPoint, int *pEnd ) {
290 // if (isInImage(tPoint)) {
291 // CvPoint tCurrent;
292 // CvPoint tNext = {0,0};
293 // unsigned char *pNeighbor;
294 // bool bRemove = false;
295 // for ( tCurrent.y = tPoint.y - 1; tCurrent.y <= tPoint.y+1; tCurrent.y++ ) {
296 // tCurrent.x = tPoint.x - 1;
297 // pNeighbor = getImgEdge ( tCurrent );
298 // for ( ; tCurrent.x <= tPoint.x+1; tCurrent.x++ ) {
299 // if ( *pNeighbor >= mEdgeToProcess ) {
300 // if ( ( tCurrent.x == tPoint.x ) && ( tCurrent.y == tPoint.y ) ) {
301 // *pNeighbor = mEdgeProcessed;
302 // mEdges[mNrOfEdges] = tPoint;
303 // *pEnd = mNrOfEdges;
304 // mNrOfEdges++;
305 // } else {
306 // if ( bRemove ) {
307 // *pNeighbor = mEdgeProcessed;
308 // } else {
309 // bRemove = true;
310 // tNext = tCurrent;
311 // }
312 // }
313 // }
314 // pNeighbor++;
315 // }
316 // }
317 // if ( bRemove ) {
318 // Trace_Simple ( tNext, pEnd );
319 // }
320 // }
321 // }
322 
323 void Contour::Trace_Simple ( CvPoint tPoint, int *pEnd ) {
324  /*
325  IplImage *pImgSimple = cvCreateImage(cvSize(mImgWidth, mImgHeight),8,3);
326  cvZero(pImgSimple);
327  cvNamedWindow ( "ImgSimple", 1 );
328  for(int i = 0; i < mImgWidth * mImgHeight; i++){
329  pImgSimple->imageData[i*3] = mpImgEdge[i];
330  }
331  cvShowImage ( "ImgSimple", pImgSimple );
332  cvWaitKey(100);
333  */
334  if (isInImage(tPoint)) {
335  unsigned char *pPix = getImgEdge ( tPoint );
336  CvPoint tCurrent = tPoint;
337  bool bEnd = false;
338  bool bStart = false;
339  std::stack<CvPoint> trace_to_start;
340  std::stack<CvPoint> trace_to_end;
341  std::stack<CvPoint> *pEdgeStack = &trace_to_start;
342  while (bEnd == false) {
343  /*
344  if(bStart == false) pImgSimple->imageData[( tCurrent.y * mImgWidth + tCurrent.x )*3+1] = 0xFF;
345  else pImgSimple->imageData[( tCurrent.y * mImgWidth + tCurrent.x )*3+2] = 0xFF;
346  cvShowImage ( "ImgSimple", pImgSimple );
347  cvWaitKey(10);
348  */
349  *pPix = mEdgeProcessed;
350  pEdgeStack->push(tCurrent);
351  if (pPix[-mImgWidth-1] >= mEdgeToProcess) {
352  pPix = pPix-mImgWidth-1;
353  tCurrent.x--, tCurrent.y--;
354  } else if (pPix[-mImgWidth] >= mEdgeToProcess) {
355  pPix = pPix-mImgWidth;
356  tCurrent.y--;
357  } else if ( pPix[-mImgWidth+1] >= mEdgeToProcess) {
358  pPix = pPix-mImgWidth+1;
359  tCurrent.x++, tCurrent.y--;
360  } else if (pPix[-1] >= mEdgeToProcess) {
361  pPix = pPix-1;
362  tCurrent.x--;
363  } else if (pPix[+1] >= mEdgeToProcess) {
364  pPix = pPix+1;
365  tCurrent.x++;
366  } else if (pPix[mImgWidth-1] >= mEdgeToProcess) {
367  pPix = pPix + mImgWidth-1;
368  tCurrent.x--, tCurrent.y++;
369  } else if (pPix[mImgWidth] >= mEdgeToProcess) {
370  pPix = pPix + mImgWidth;
371  tCurrent.y++;
372  } else if (pPix[mImgWidth+1] >= mEdgeToProcess) {
373  pPix = pPix + mImgWidth + 1;
374  tCurrent.x++, tCurrent.y++;
375  } else {
376  if (bStart == false) {
377  bStart = true;
378  while (!trace_to_start.empty()) {
379  trace_to_end.push(trace_to_start.top());
380  trace_to_start.pop();
381  }
382  pEdgeStack = &trace_to_end;
383  tCurrent = pEdgeStack->top();
384  pEdgeStack->pop();
385  pPix = getImgEdge ( tCurrent );
386  } else {
387  bEnd = true;
388  }
389  }
390  }
391  while (!pEdgeStack->empty()) {
392  CvPoint p = pEdgeStack->top();
393  mEdges[mNrOfEdges++] = p;
394  pEdgeStack->pop();
395  }
396 
397  *pEnd = (mNrOfEdges-1);
398  }
399 }
400 
402  CvPoint tPoint = cvPoint(0,0);
403  cv::Range range(0,0);
404  for ( tPoint.y = 1; tPoint.y < ( int ) mImgHeight-1; tPoint.y++ ) {
405  tPoint.x = 1;
406  unsigned char *pCurrent = getImgEdge ( tPoint );
407  for ( ; tPoint.x < ( int ) mImgWidth-1; tPoint.x++ ) {
408  if ( *pCurrent >= mEdgeToProcess ) {
409  range.start = mNrOfEdges;
410  Trace_Contour ( tPoint, &range.end, 0 );
411  mSegments.push_back ( range );
412  //*pCurrent = 0;
413  }
414  pCurrent++;
415  }
416  }
417 }
418 
419 void Contour::Trace_Contour ( CvPoint tPoint, int *pEnd, unsigned int iCommingFromEdge ) {
420  /*
421  IplImage *pImgSimple = cvCreateImage(cvSize(mImgWidth, mImgHeight),8,3);
422  cvZero(pImgSimple);
423  cvNamedWindow ( "ImgSimple", 1 );
424  for(int i = 0; i < mImgWidth * mImgHeight; i++){
425  pImgSimple->imageData[i*3] = mpImgEdge[i];
426  }
427  */
428  if (isInImage(tPoint)) {
429  unsigned char *pPix = getImgEdge ( tPoint );
430  CvPoint tCurrent = tPoint;
431  bool bEnd = false;
432  bool bStart = false;
433  std::stack<CvPoint> trace_to_start;
434  std::stack<CvPoint> trace_to_end;
435  std::stack<CvPoint> *pEdgeStack = &trace_to_start;
436  while (bEnd == false) {
437  *pPix = mEdgeProcessed;
438  pEdgeStack->push(tCurrent);
439  if (pPix[-mImgWidth-1] >= mEdgeToProcess) {
440  pPix = pPix-mImgWidth-1;
441  tCurrent.x--, tCurrent.y--;
442  } else if (pPix[-mImgWidth] >= mEdgeToProcess) {
443  pPix = pPix-mImgWidth;
444  tCurrent.y--;
445  } else if ( pPix[-mImgWidth+1] >= mEdgeToProcess) {
446  pPix = pPix-mImgWidth+1;
447  tCurrent.x++, tCurrent.y--;
448  } else if (pPix[-1] >= mEdgeToProcess) {
449  pPix = pPix-1;
450  tCurrent.x--;
451  } else if (pPix[+1] >= mEdgeToProcess) {
452  pPix = pPix+1;
453  tCurrent.x++;
454  } else if (pPix[mImgWidth-1] >= mEdgeToProcess) {
455  pPix = pPix + mImgWidth-1;
456  tCurrent.x--, tCurrent.y++;
457  } else if (pPix[mImgWidth] >= mEdgeToProcess) {
458  pPix = pPix + mImgWidth;
459  tCurrent.y++;
460  } else if (pPix[mImgWidth+1] >= mEdgeToProcess) {
461  pPix = pPix + mImgWidth + 1;
462  tCurrent.x++, tCurrent.y++;
463  } else {
464  if (bStart == false) {
465  bStart = true;
466  while (!trace_to_start.empty()) {
467  trace_to_end.push(trace_to_start.top());
468  trace_to_start.pop();
469  }
470  pEdgeStack = &trace_to_end;
471  tCurrent = pEdgeStack->top();
472  pPix = getImgEdge ( tCurrent );
473  } else {
474  bEnd = true;
475  }
476  }
477  }
478  while (!pEdgeStack->empty()) {
479  mEdges[mNrOfEdges++] = pEdgeStack->top();
480  pEdgeStack->pop();
481  }
482  *pEnd = mNrOfEdges;
483  }
484 }
485 
486 
488  CvPoint tPoint = cvPoint(0,0);;
489  cv::Range range(0,0);
490  for ( tPoint.y = 1; tPoint.y < ( int ) mImgHeight-1; tPoint.y++ ) {
491  tPoint.x = 1;
492  unsigned char *pCurrent = getImgEdge ( tPoint );
493  for ( ; tPoint.x < ( int ) mImgWidth-1; tPoint.x++ ) {
494  if ( *pCurrent >= mEdgeToProcess ) {
495  range.start = mNrOfEdges;
496  Trace_Gradient ( tPoint, &range.end );
497  mSegments.push_back ( range );
498  //*pCurrent = 0;
499  }
500  pCurrent++;
501  }
502  }
503 }
504 
505 void Contour::Trace_Gradient ( CvPoint tPoint, int *pEnd ) {
506  if (isInImage(tPoint)) {
507  CvPoint tCurrent = cvPoint(0,0);;
508  CvPoint tNext = cvPoint(0,0);;
509  bool bRemove = false;
510  unsigned char *pNeighbor;
511  int iEdgeDirection;
513  mAngle8Bit[mNrOfEdges] = ( ( unsigned char* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
514  }
515  iEdgeDirection = GetImgDirectionIndex ( tPoint );
516  int *pIndex = ( int* ) ppGradientWeightsField[iEdgeDirection];
517  for ( int i = 0; i < 9; i++ ) {
518  tCurrent = GetNeighborPoint ( tPoint, pIndex[i] );
519  pNeighbor = getImgEdge ( tCurrent );
520  if ( *pNeighbor >= mEdgeToProcess ) {
521  if ( pIndex[i] == 4 ) {
522  //Center
523  *pNeighbor = mEdgeProcessed;
524  mEdges[mNrOfEdges] = tPoint;
525  *pEnd = mNrOfEdges;
526  mNrOfEdges++;
527  } else {
528  if ( bRemove ) {
529  *pNeighbor = mEdgeProcessed;
530  } else {
531  bRemove = true;
532  tNext = tCurrent;
533  }
534  }
535  }
536  }
537  if ( bRemove ) {
538  Trace_Gradient ( tNext, pEnd );
539  }
540  }
541 }
542 
543 
545  CvPoint tPoint = cvPoint(0,0);;
546  cv::Range range(0,0);
547  for ( tPoint.y = 1; tPoint.y < ( int ) mImgHeight-1; tPoint.y++ ) {
548  tPoint.x = 1;
549  unsigned char *pCurrent = getImgEdge ( tPoint );
550  for ( ; tPoint.x < ( int ) mImgWidth-1; tPoint.x++ ) {
551  if ( *pCurrent >= mEdgeToProcess ) {
552  range.start = mNrOfEdges;
553  Trace_Complex ( tPoint, &range.end, 0 );
554  mSegments.push_back ( range );
555  //*pCurrent = 0;
556  }
557  pCurrent++;
558  }
559  }
560 }
561 
562 void Contour::Trace_Complex ( CvPoint tPoint, int *pEnd, unsigned int iCommingFromEdge ) {
563  if (isInImage(tPoint)) {
564  CvPoint tCurrent;
565  CvPoint tNext = cvPoint(0,0);;
566  bool bRemove = false;
567  unsigned char *pNeighbor = NULL;
568  unsigned int iGointToEdge = 0;
569  int pSum[9];
570  int pIndex[9];
571  int iEdgeDirection;
573  mAngle8Bit[mNrOfEdges] = ( ( unsigned char* ) mpImgEdgeDirection ) [tPoint.y*mImgWidth + tPoint.x];
574  }
575  iEdgeDirection = GetImgDirectionIndex ( tPoint );
576  SumArrayMatrix ( ( int * ) pppDirectionWeightsField[iEdgeDirection],
577  ( int * ) pppCommingFromEdgeWeightsField[iCommingFromEdge],
578  ( int * ) pSum, 9 );
579  SortArrayIndexes ( pSum, pIndex, 9 );
580  for ( int i = 0; i < 9; i++ ) {
581  tCurrent = GetNeighborPoint ( tPoint, pIndex[i] );
582  pNeighbor = getImgEdge ( tCurrent );
583  if ( *pNeighbor >= mEdgeToProcess ) {
584  if ( pIndex[i] == 4 ) {
585  //Center
586  *pNeighbor = mEdgeProcessed;
587  mEdges[mNrOfEdges] = tPoint;
588  *pEnd = mNrOfEdges;
589  mNrOfEdges++;
590  } else {
591  if ( bRemove ) {
592  *pNeighbor = mEdgeProcessed;
593  } else {
594  bRemove = true;
595  tNext = tCurrent;
596  iGointToEdge = 8-pIndex[i];
597  }
598  }
599  }
600  }
601  if ( bRemove ) {
602  Trace_Complex ( tNext, pEnd, iGointToEdge );
603  }
604  }
605 }
606 
607 const CvPoint Contour::GetNeighborPoint ( CvPoint tPoint, int iNeighborIndex ) {
608  switch ( iNeighborIndex ) {
609  case 0:
610  tPoint.x += -1;
611  tPoint.y += -1;
612  break;
613  case 1:
614  tPoint.x += 0;
615  tPoint.y += -1;
616  break;
617  case 2:
618  tPoint.x += +1;
619  tPoint.y += -1;
620  break;
621  case 3:
622  tPoint.x += -1;
623  tPoint.y += 0;
624  break;
625  case 4:
626  tPoint.x += 0;
627  tPoint.y += 0;
628  break;
629  case 5:
630  tPoint.x += +1;
631  tPoint.y += 0;
632  break;
633  case 6:
634  tPoint.x += -1;
635  tPoint.y += +1;
636  break;
637  case 7:
638  tPoint.x += 0;
639  tPoint.y += +1;
640  break;
641  case 8:
642  tPoint.x += +1;
643  tPoint.y += +1;
644  break;
645  }
646  return tPoint;
647 }
648 int Contour::GetEdgeListSplittedXY (std::vector<cv::Point_<int> > &rEdges, std::vector<unsigned char> **ppAngle8Bit) {
649 
650  rEdges.resize ( mEdges.size() );
651  for (unsigned int i = 0; i < mEdges.size(); i++) {
652  rEdges[i] = mEdges[i];
653  }
654  if (ppAngle8Bit != NULL) {
655  *ppAngle8Bit = &mAngle8Bit;
656  }
657  return mEdges.size();
658 }
659 
660 const void Contour::SortArrayIndexes ( int *pArray, int *pIndexes, const int iSize ) {
661  int iMax = -1;
662  int iMin = iMax;
663  int iMaxIndex = 0;
664  for ( int j = 0; j < iSize; j++ ) {
665  for ( int i = 0; i < iSize; i++ ) {
666  if ( pArray[i] > iMax ) {
667  iMax = pArray[i];
668  iMaxIndex = i;
669  }
670  if ( pArray[i] < iMin ) {
671  iMin = pArray[i];
672  }
673  }
674  pIndexes[j] = iMaxIndex;
675  pArray[iMaxIndex] = iMin;
676  iMax = iMin;
677  }
678 }
679 
680 void Contour::GetAbnormitiesInEdgesImage ( IplImage *ptImgEdge, std::vector<CvPoint> *pAbnormities, uchar iEdgeStrength ) {
681  pAbnormities->clear();
682  bool bAbnormities;
683  CvPoint tPoint;
684  for ( tPoint.y = 1; tPoint.y < ptImgEdge->height-1; tPoint.y++ ) {
685  unsigned char *pRow0 = ( unsigned char * ) ptImgEdge->imageData + ptImgEdge->width* ( tPoint.y-1 );
686  unsigned char *pRow1 = pRow0 + ptImgEdge->width;
687  unsigned char *pRow2 = pRow1 + ptImgEdge->width;
688  for ( tPoint.x = 1; tPoint.x < ptImgEdge->width-1; tPoint.x++ ) {
689  bAbnormities = false;
690  if ( pRow1[1] > iEdgeStrength ) {
691  int iNoOfNeighbors = 0;
692  if ( pRow0[0] > iEdgeStrength ) {
693  iNoOfNeighbors++;
694  if ( ( pRow0[1] > iEdgeStrength ) || ( pRow1[0] > iEdgeStrength ) ) {
695  bAbnormities = true;
696  }
697  }
698  if ( pRow0[1] > iEdgeStrength ) {
699  iNoOfNeighbors++;
700  if ( ( pRow0[0] > iEdgeStrength ) || ( pRow0[2] > iEdgeStrength ) ) {
701  bAbnormities = true;
702  }
703  }
704  if ( pRow0[2] > iEdgeStrength ) {
705  iNoOfNeighbors++;
706  if ( ( pRow0[1] > iEdgeStrength ) || ( pRow1[2] > iEdgeStrength ) ) {
707  bAbnormities = true;
708  }
709  }
710  if ( pRow1[0] > iEdgeStrength ) {
711  iNoOfNeighbors++;
712  if ( ( pRow0[0] > iEdgeStrength ) || ( pRow2[0] > iEdgeStrength ) ) {
713  bAbnormities = true;
714  }
715  }
716  if ( pRow1[2] > iEdgeStrength ) {
717  iNoOfNeighbors++;
718  if ( ( pRow0[2] > iEdgeStrength ) || ( pRow2[2] > iEdgeStrength ) ) {
719  bAbnormities = true;
720  }
721  }
722  if ( pRow2[0] > iEdgeStrength ) {
723  iNoOfNeighbors++;
724  if ( ( pRow1[0] > iEdgeStrength ) || ( pRow2[1] > iEdgeStrength ) ) {
725  bAbnormities = true;
726  }
727  }
728  if ( pRow2[1] > iEdgeStrength ) {
729  iNoOfNeighbors++;
730  if ( ( pRow2[0] > iEdgeStrength ) || ( pRow2[2] > iEdgeStrength ) ) {
731  bAbnormities = true;
732  }
733  }
734  if ( pRow2[2] > iEdgeStrength ) {
735  iNoOfNeighbors++;
736  if ( ( pRow2[1] > iEdgeStrength ) || ( pRow1[2] > iEdgeStrength ) ) {
737  bAbnormities = true;
738  }
739  }
740  if ( bAbnormities ) {
741  pAbnormities->push_back ( tPoint );
742  }
743  }
744  pRow0++;
745  pRow1++;
746  pRow2++;
747  }
748  }
749 
750 }
751 
752 std::vector<cv::Range> Contour::getSegmentIndexes() {
753  return mSegments;
754 }
755 
756 } //namespace V4R
int GetEdgeListSplittedXY(std::vector< cv::Point_< int > > &rEdges, std::vector< unsigned char > **ppAngle8Bit=NULL)
Returns number of edges and edges in the arguments.
Definition: contour.cpp:648
void Linking_Contour()
Definition: contour.cpp:401
static const float fPi
Definition: contour.h:149
int mImgWidth
Definition: contour.h:139
static const int pppDirectionWeightsField[4][3][3]
Definition: contour.h:145
int GetImgDirectionIndex(CvPoint tPoint)
Definition: contour.cpp:193
static const CvPoint GetNeighborPoint(CvPoint pPtrCenter, int iNeighborIndex)
Definition: contour.cpp:607
void Trace_Simple(CvPoint tPoint, int *pEnd)
Definition: contour.cpp:323
std::vector< cv::Range > getSegmentIndexes()
the indexes of the contour segments
Definition: contour.cpp:752
void Perform(unsigned char *pImgEdgeStrength, int defEdgeLinkMode=MODE_CONTOUR, void *pImgEdgeDirection=NULL, int defImgEdgeDirectionType=ANGLE_8U)
Starts the edge linking with a certain mode.
Definition: contour.cpp:235
static const void SortArrayIndexes(int *pArray, int *pIndexes, const int iSize)
Definition: contour.cpp:660
std::vector< CvPoint > mEdges
Definition: contour.h:152
void Init(unsigned int iImgWidth, unsigned int iImgHeight, bool bAllowToModifyTheSources=false, unsigned char iEdgeToProcess=0xFF, unsigned char iEdgeInProcess=0xFF-1, unsigned char iEdgeProcessed=0xFF-2, unsigned char iEdgeStrengthRemoved=0)
Inititalized the class and reserves the momory needed.
Definition: contour.cpp:178
static const int ANGLE_32F
Static const variable used to define the source format of a gradient image as atan2(dy, dx) of the edge The format ANGLE_32F means values from -PI to +PI.
Definition: contour.h:38
unsigned char mEdgeInProcess
Definition: contour.h:143
static const int ppGradientWeightsField[4][9]
Definition: contour.h:146
static const int ANGLE_64F
Static const variable used to define the source format of a gradient image as atan2(dy, dx) of the edge The format ANGLE_64F means values from -PI to +PI.
Definition: contour.h:43
int mdefEdgeLinkMode
Definition: contour.h:138
std::vector< unsigned char > mAngle8Bit
Definition: contour.h:153
unsigned int mNrOfEdges
Definition: contour.h:154
int mdImgEdgeDirectionType
Definition: contour.h:137
int getContours(std::vector< std::vector< cv::Point > > &contours, unsigned min_length=0)
Returns the contour as vector of vector points.
Definition: contour.cpp:147
void GetAbnormitiesInEdgesImage(IplImage *ptImgEdge, std::vector< CvPoint > *pAbnormities, uchar iEdgeStrength=0)
Find egde contour Abnormities in edge image.
Definition: contour.cpp:680
void Trace_Contour(CvPoint tPoint, int *pEnd, unsigned int iCommingFromEdge)
Definition: contour.cpp:419
int mImgHeight
Definition: contour.h:140
static const int MODE_COMPLEX
Static const variable used to define the methode used to find the contour (linked edges) ...
Definition: contour.h:60
static const int pppCommingFromEdgeWeightsField[9][3][3]
Definition: contour.h:147
unsigned char mEdgeProcessed
Definition: contour.h:144
static const double dPi
Definition: contour.h:150
void Linking_Gradient()
Definition: contour.cpp:487
void Linking_Simple()
Definition: contour.cpp:271
unsigned char * getImgEdge(CvPoint tPoint)
Definition: contour.h:173
unsigned char * mpImgEdge
Definition: contour.h:135
void RelaseMemory()
Definition: contour.cpp:132
void Trace_Complex(CvPoint tPoint, int *pEnd, unsigned int iCommingFromEdge)
Definition: contour.cpp:562
std::vector< cv::Range > mSegments
Definition: contour.h:155
void Draw(unsigned char *pImgRGB)
Draws the detected contours in a RGB image with radom colours.
Definition: contour.cpp:163
void * mpImgEdgeDirection
Definition: contour.h:136
static const int MODE_GRAIDENT
Static const variable used to define the methode used to find the contour (linked edges) ...
Definition: contour.h:56
void SumArrayMatrix(int *pMatrixA, int *pMatrixB, int *pSum, const int iSize)
Definition: contour.h:176
bool mbAllowToModifyTheSources
Definition: contour.h:141
static const int MODE_CONTOUR
Static const variable used to define the methode used to find the contour (linked edges) ...
Definition: contour.h:52
void AllocateMemory()
Definition: contour.cpp:122
static const int ppContourWeightsField[9][9]
Definition: contour.h:148
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
bool isInImage(const CvPoint &p)
Definition: contour.h:179
void Trace_Gradient(CvPoint tPoint, int *pEnd)
Definition: contour.cpp:505
static const int MODE_SIMPLE
Static const variable used to define the methode used to find the contour (linked edges) ...
Definition: contour.h:48
unsigned char mEdgeToProcess
Definition: contour.h:142
void Linking_Complex()
Definition: contour.cpp:544
static const int ANGLE_8U
Static const variable used to define the source format of a gradient image as atan2(dy, dx) of the edge The format ANGLE_8U means zero rad are 0, +PI and -PI are 0x7F.
Definition: contour.h:33


tuw_ellipses
Author(s): Markus Bader
autogenerated on Mon Jun 10 2019 15:42:10