ffilldemo.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "opencv2/imgproc.hpp"
  2. #include "opencv2/imgcodecs.hpp"
  3. #include "opencv2/videoio.hpp"
  4. #include "opencv2/highgui.hpp"
  5. #include <iostream>
  6. using namespace cv;
  7. using namespace std;
  8. static void help(char** argv)
  9. {
  10. cout << "\nThis program demonstrated the floodFill() function\n"
  11. "Call:\n"
  12. << argv[0]
  13. << " [image_name -- Default: fruits.jpg]\n" << endl;
  14. cout << "Hot keys: \n"
  15. "\tESC - quit the program\n"
  16. "\tc - switch color/grayscale mode\n"
  17. "\tm - switch mask mode\n"
  18. "\tr - restore the original image\n"
  19. "\ts - use null-range floodfill\n"
  20. "\tf - use gradient floodfill with fixed(absolute) range\n"
  21. "\tg - use gradient floodfill with floating(relative) range\n"
  22. "\t4 - use 4-connectivity mode\n"
  23. "\t8 - use 8-connectivity mode\n" << endl;
  24. }
  25. Mat image0, image, gray, mask;
  26. int ffillMode = 1;
  27. int loDiff = 20, upDiff = 20;
  28. int connectivity = 4;
  29. int isColor = true;
  30. bool useMask = false;
  31. int newMaskVal = 255;
  32. static void onMouse( int event, int x, int y, int, void* )
  33. {
  34. if( event != EVENT_LBUTTONDOWN )
  35. return;
  36. Point seed = Point(x,y);
  37. int lo = ffillMode == 0 ? 0 : loDiff;
  38. int up = ffillMode == 0 ? 0 : upDiff;
  39. int flags = connectivity + (newMaskVal << 8) +
  40. (ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0);
  41. int b = (unsigned)theRNG() & 255;
  42. int g = (unsigned)theRNG() & 255;
  43. int r = (unsigned)theRNG() & 255;
  44. Rect ccomp;
  45. Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);
  46. Mat dst = isColor ? image : gray;
  47. int area;
  48. if( useMask )
  49. {
  50. threshold(mask, mask, 1, 128, THRESH_BINARY);
  51. area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),
  52. Scalar(up, up, up), flags);
  53. imshow( "mask", mask );
  54. }
  55. else
  56. {
  57. area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),
  58. Scalar(up, up, up), flags);
  59. }
  60. imshow("image", dst);
  61. cout << area << " pixels were repainted\n";
  62. }
  63. int main( int argc, char** argv )
  64. {
  65. cv::CommandLineParser parser (argc, argv,
  66. "{help h | | show help message}{@image|fruits.jpg| input image}"
  67. );
  68. if (parser.has("help"))
  69. {
  70. parser.printMessage();
  71. return 0;
  72. }
  73. string filename = parser.get<string>("@image");
  74. image0 = imread(samples::findFile(filename), 1);
  75. if( image0.empty() )
  76. {
  77. cout << "Image empty\n";
  78. parser.printMessage();
  79. return 0;
  80. }
  81. help(argv);
  82. image0.copyTo(image);
  83. cvtColor(image0, gray, COLOR_BGR2GRAY);
  84. mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
  85. namedWindow( "image", 0 );
  86. createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
  87. createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
  88. setMouseCallback( "image", onMouse, 0 );
  89. for(;;)
  90. {
  91. imshow("image", isColor ? image : gray);
  92. char c = (char)waitKey(0);
  93. if( c == 27 )
  94. {
  95. cout << "Exiting ...\n";
  96. break;
  97. }
  98. switch( c )
  99. {
  100. case 'c':
  101. if( isColor )
  102. {
  103. cout << "Grayscale mode is set\n";
  104. cvtColor(image0, gray, COLOR_BGR2GRAY);
  105. mask = Scalar::all(0);
  106. isColor = false;
  107. }
  108. else
  109. {
  110. cout << "Color mode is set\n";
  111. image0.copyTo(image);
  112. mask = Scalar::all(0);
  113. isColor = true;
  114. }
  115. break;
  116. case 'm':
  117. if( useMask )
  118. {
  119. destroyWindow( "mask" );
  120. useMask = false;
  121. }
  122. else
  123. {
  124. namedWindow( "mask", 0 );
  125. mask = Scalar::all(0);
  126. imshow("mask", mask);
  127. useMask = true;
  128. }
  129. break;
  130. case 'r':
  131. cout << "Original image is restored\n";
  132. image0.copyTo(image);
  133. cvtColor(image, gray, COLOR_BGR2GRAY);
  134. mask = Scalar::all(0);
  135. break;
  136. case 's':
  137. cout << "Simple floodfill mode is set\n";
  138. ffillMode = 0;
  139. break;
  140. case 'f':
  141. cout << "Fixed Range floodfill mode is set\n";
  142. ffillMode = 1;
  143. break;
  144. case 'g':
  145. cout << "Gradient (floating range) floodfill mode is set\n";
  146. ffillMode = 2;
  147. break;
  148. case '4':
  149. cout << "4-connectivity mode is set\n";
  150. connectivity = 4;
  151. break;
  152. case '8':
  153. cout << "8-connectivity mode is set\n";
  154. connectivity = 8;
  155. break;
  156. }
  157. }
  158. return 0;
  159. }