PageRenderTime 271ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/opencv/src/distrans.c

https://gitlab.com/juan-cardelino/misc_projects
C | 189 lines | 157 code | 27 blank | 5 comment | 56 complexity | f9e94087c3109dbbe9db7e5a685e34db MD5 | raw file
  1. #define CV_NO_BACKWARD_COMPATIBILITY
  2. #ifdef _CH_
  3. #pragma package <opencv>
  4. #endif
  5. #include "cv.h"
  6. #include "highgui.h"
  7. #include <stdio.h>
  8. char wndname[] = "Distance transform";
  9. char tbarname[] = "Threshold";
  10. int mask_size = CV_DIST_MASK_5;
  11. int build_voronoi = 0;
  12. int edge_thresh = 100;
  13. int dist_type = CV_DIST_L1;
  14. // The output and temporary images
  15. IplImage* dist = 0;
  16. IplImage* dist8u1 = 0;
  17. IplImage* dist8u2 = 0;
  18. IplImage* dist8u = 0;
  19. IplImage* dist32s = 0;
  20. IplImage* gray = 0;
  21. IplImage* edge = 0;
  22. IplImage* labels = 0;
  23. // threshold trackbar callback
  24. void on_trackbar( int dummy )
  25. {
  26. static const uchar colors[][3] =
  27. {
  28. {0,0,0},
  29. {255,0,0},
  30. {255,128,0},
  31. {255,255,0},
  32. {0,255,0},
  33. {0,128,255},
  34. {0,255,255},
  35. {0,0,255},
  36. {255,0,255}
  37. };
  38. int msize = mask_size;
  39. int _dist_type = build_voronoi ? CV_DIST_L2 : dist_type;
  40. cvThreshold( gray, edge, (float)edge_thresh, (float)edge_thresh, CV_THRESH_BINARY );
  41. if( build_voronoi )
  42. msize = CV_DIST_MASK_5;
  43. if( _dist_type == CV_DIST_L1 )
  44. {
  45. cvDistTransform( edge, edge, _dist_type, msize, NULL, NULL );
  46. cvConvert( edge, dist );
  47. }
  48. else
  49. cvDistTransform( edge, dist, _dist_type, msize, NULL, build_voronoi ? labels : NULL );
  50. if( !build_voronoi )
  51. {
  52. // begin "painting" the distance transform result
  53. cvConvertScale( dist, dist, 5000.0, 0 );
  54. cvPow( dist, dist, 0.5 );
  55. cvConvertScale( dist, dist32s, 1.0, 0.5 );
  56. cvAndS( dist32s, cvScalarAll(255), dist32s, 0 );
  57. cvConvertScale( dist32s, dist8u1, 1, 0 );
  58. cvConvertScale( dist32s, dist32s, -1, 0 );
  59. cvAddS( dist32s, cvScalarAll(255), dist32s, 0 );
  60. cvConvertScale( dist32s, dist8u2, 1, 0 );
  61. cvMerge( dist8u1, dist8u2, dist8u2, 0, dist8u );
  62. // end "painting" the distance transform result
  63. }
  64. else
  65. {
  66. int i, j;
  67. for( i = 0; i < labels->height; i++ )
  68. {
  69. int* ll = (int*)(labels->imageData + i*labels->widthStep);
  70. float* dd = (float*)(dist->imageData + i*dist->widthStep);
  71. uchar* d = (uchar*)(dist8u->imageData + i*dist8u->widthStep);
  72. for( j = 0; j < labels->width; j++ )
  73. {
  74. int idx = ll[j] == 0 || dd[j] == 0 ? 0 : (ll[j]-1)%8 + 1;
  75. int b = cvRound(colors[idx][0]);
  76. int g = cvRound(colors[idx][1]);
  77. int r = cvRound(colors[idx][2]);
  78. d[j*3] = (uchar)b;
  79. d[j*3+1] = (uchar)g;
  80. d[j*3+2] = (uchar)r;
  81. }
  82. }
  83. }
  84. cvShowImage( wndname, dist8u );
  85. }
  86. int main( int argc, char** argv )
  87. {
  88. char* filename = argc == 2 ? argv[1] : (char*)"stuff.jpg";
  89. if( (gray = cvLoadImage( filename, 0 )) == 0 )
  90. return -1;
  91. printf( "Hot keys: \n"
  92. "\tESC - quit the program\n"
  93. "\tC - use C/Inf metric\n"
  94. "\tL1 - use L1 metric\n"
  95. "\tL2 - use L2 metric\n"
  96. "\t3 - use 3x3 mask\n"
  97. "\t5 - use 5x5 mask\n"
  98. "\t0 - use precise distance transform\n"
  99. "\tv - switch Voronoi diagram mode on/off\n"
  100. "\tSPACE - loop through all the modes\n" );
  101. dist = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32F, 1 );
  102. dist8u1 = cvCloneImage( gray );
  103. dist8u2 = cvCloneImage( gray );
  104. dist8u = cvCreateImage( cvGetSize(gray), IPL_DEPTH_8U, 3 );
  105. dist32s = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32S, 1 );
  106. edge = cvCloneImage( gray );
  107. labels = cvCreateImage( cvGetSize(gray), IPL_DEPTH_32S, 1 );
  108. cvNamedWindow( wndname, 1 );
  109. cvCreateTrackbar( tbarname, wndname, &edge_thresh, 255, on_trackbar );
  110. for(;;)
  111. {
  112. int c;
  113. // Call to update the view
  114. on_trackbar(0);
  115. c = cvWaitKey(0);
  116. if( (char)c == 27 )
  117. break;
  118. if( (char)c == 'c' || (char)c == 'C' )
  119. dist_type = CV_DIST_C;
  120. else if( (char)c == '1' )
  121. dist_type = CV_DIST_L1;
  122. else if( (char)c == '2' )
  123. dist_type = CV_DIST_L2;
  124. else if( (char)c == '3' )
  125. mask_size = CV_DIST_MASK_3;
  126. else if( (char)c == '5' )
  127. mask_size = CV_DIST_MASK_5;
  128. else if( (char)c == '0' )
  129. mask_size = CV_DIST_MASK_PRECISE;
  130. else if( (char)c == 'v' )
  131. build_voronoi ^= 1;
  132. else if( (char)c == ' ' )
  133. {
  134. if( build_voronoi )
  135. {
  136. build_voronoi = 0;
  137. mask_size = CV_DIST_MASK_3;
  138. dist_type = CV_DIST_C;
  139. }
  140. else if( dist_type == CV_DIST_C )
  141. dist_type = CV_DIST_L1;
  142. else if( dist_type == CV_DIST_L1 )
  143. dist_type = CV_DIST_L2;
  144. else if( mask_size == CV_DIST_MASK_3 )
  145. mask_size = CV_DIST_MASK_5;
  146. else if( mask_size == CV_DIST_MASK_5 )
  147. mask_size = CV_DIST_MASK_PRECISE;
  148. else if( mask_size == CV_DIST_MASK_PRECISE )
  149. build_voronoi = 1;
  150. }
  151. }
  152. cvReleaseImage( &gray );
  153. cvReleaseImage( &edge );
  154. cvReleaseImage( &dist );
  155. cvReleaseImage( &dist8u );
  156. cvReleaseImage( &dist8u1 );
  157. cvReleaseImage( &dist8u2 );
  158. cvReleaseImage( &dist32s );
  159. cvReleaseImage( &labels );
  160. cvDestroyWindow( wndname );
  161. return 0;
  162. }