bgfg_segm.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html
  4. #include "opencv2/core.hpp"
  5. #include "opencv2/imgproc.hpp"
  6. #include "opencv2/video.hpp"
  7. #include "opencv2/videoio.hpp"
  8. #include "opencv2/highgui.hpp"
  9. #include <iostream>
  10. using namespace std;
  11. using namespace cv;
  12. int main(int argc, const char** argv)
  13. {
  14. const String keys = "{c camera | 0 | use video stream from camera (device index starting from 0) }"
  15. "{fn file_name | | use video file as input }"
  16. "{m method | mog2 | method: background subtraction algorithm ('knn', 'mog2')}"
  17. "{h help | | show help message}";
  18. CommandLineParser parser(argc, argv, keys);
  19. parser.about("This sample demonstrates background segmentation.");
  20. if (parser.has("help"))
  21. {
  22. parser.printMessage();
  23. return 0;
  24. }
  25. int camera = parser.get<int>("camera");
  26. String file = parser.get<String>("file_name");
  27. String method = parser.get<String>("method");
  28. if (!parser.check())
  29. {
  30. parser.printErrors();
  31. return 1;
  32. }
  33. VideoCapture cap;
  34. if (file.empty())
  35. cap.open(camera);
  36. else
  37. {
  38. file = samples::findFileOrKeep(file); // ignore gstreamer pipelines
  39. cap.open(file.c_str());
  40. }
  41. if (!cap.isOpened())
  42. {
  43. cout << "Can not open video stream: '" << (file.empty() ? "<camera>" : file) << "'" << endl;
  44. return 2;
  45. }
  46. Ptr<BackgroundSubtractor> model;
  47. if (method == "knn")
  48. model = createBackgroundSubtractorKNN();
  49. else if (method == "mog2")
  50. model = createBackgroundSubtractorMOG2();
  51. if (!model)
  52. {
  53. cout << "Can not create background model using provided method: '" << method << "'" << endl;
  54. return 3;
  55. }
  56. cout << "Press <space> to toggle background model update" << endl;
  57. cout << "Press 's' to toggle foreground mask smoothing" << endl;
  58. cout << "Press ESC or 'q' to exit" << endl;
  59. bool doUpdateModel = true;
  60. bool doSmoothMask = false;
  61. Mat inputFrame, frame, foregroundMask, foreground, background;
  62. for (;;)
  63. {
  64. // prepare input frame
  65. cap >> inputFrame;
  66. if (inputFrame.empty())
  67. {
  68. cout << "Finished reading: empty frame" << endl;
  69. break;
  70. }
  71. const Size scaledSize(640, 640 * inputFrame.rows / inputFrame.cols);
  72. resize(inputFrame, frame, scaledSize, 0, 0, INTER_LINEAR);
  73. // pass the frame to background model
  74. model->apply(frame, foregroundMask, doUpdateModel ? -1 : 0);
  75. // show processed frame
  76. imshow("image", frame);
  77. // show foreground image and mask (with optional smoothing)
  78. if (doSmoothMask)
  79. {
  80. GaussianBlur(foregroundMask, foregroundMask, Size(11, 11), 3.5, 3.5);
  81. threshold(foregroundMask, foregroundMask, 10, 255, THRESH_BINARY);
  82. }
  83. if (foreground.empty())
  84. foreground.create(scaledSize, frame.type());
  85. foreground = Scalar::all(0);
  86. frame.copyTo(foreground, foregroundMask);
  87. imshow("foreground mask", foregroundMask);
  88. imshow("foreground image", foreground);
  89. // show background image
  90. model->getBackgroundImage(background);
  91. if (!background.empty())
  92. imshow("mean background image", background );
  93. // interact with user
  94. const char key = (char)waitKey(30);
  95. if (key == 27 || key == 'q') // ESC
  96. {
  97. cout << "Exit requested" << endl;
  98. break;
  99. }
  100. else if (key == ' ')
  101. {
  102. doUpdateModel = !doUpdateModel;
  103. cout << "Toggle background update: " << (doUpdateModel ? "ON" : "OFF") << endl;
  104. }
  105. else if (key == 's')
  106. {
  107. doSmoothMask = !doSmoothMask;
  108. cout << "Toggle foreground mask smoothing: " << (doSmoothMask ? "ON" : "OFF") << endl;
  109. }
  110. }
  111. return 0;
  112. }