removeVideoBg.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include <opencv2/opencv.hpp>
  2. #include <iostream>
  3. #include <random>
  4. using namespace std;
  5. using namespace cv;
  6. int computeMedian(vector<int> elements) {
  7. nth_element(elements.begin(), elements.begin()+elements.size()/2, elements.end());
  8. //sort(elements.begin(),elements.end());
  9. return elements[elements.size()/2];
  10. }
  11. cv::Mat compute_median(std::vector<cv::Mat> vec) {
  12. // Note: Expects the image to be CV_8UC3
  13. cv::Mat medianImg(vec[0].rows, vec[0].cols, CV_8UC3, cv::Scalar(0, 0, 0));
  14. for(int row=0; row<vec[0].rows; row++) {
  15. for(int col=0; col<vec[0].cols; col++) {
  16. std::vector<int> elements_B;
  17. std::vector<int> elements_G;
  18. std::vector<int> elements_R;
  19. for(int imgNumber=0; imgNumber<vec.size(); imgNumber++) {
  20. int B = vec[imgNumber].at<cv::Vec3b>(row, col)[0];
  21. int G = vec[imgNumber].at<cv::Vec3b>(row, col)[1];
  22. int R = vec[imgNumber].at<cv::Vec3b>(row, col)[2];
  23. elements_B.push_back(B);
  24. elements_G.push_back(G);
  25. elements_R.push_back(R);
  26. }
  27. medianImg.at<cv::Vec3b>(row, col)[0] = computeMedian(elements_B);
  28. medianImg.at<cv::Vec3b>(row, col)[1] = computeMedian(elements_G);
  29. medianImg.at<cv::Vec3b>(row, col)[2] = computeMedian(elements_R);
  30. }
  31. }
  32. return medianImg;
  33. }
  34. int main(int argc, char const *argv[])
  35. {
  36. std::string video_file;
  37. // Read video file
  38. if(argc > 1) {
  39. video_file = argv[1];
  40. } else {
  41. video_file = "video.mp4";
  42. }
  43. VideoCapture cap(video_file);
  44. if(!cap.isOpened())
  45. cerr << "Error opening video file\n";
  46. // Randomly select 25 frames
  47. default_random_engine generator;
  48. uniform_int_distribution<int>distribution(0, cap.get(CAP_PROP_FRAME_COUNT));
  49. vector<Mat> frames;
  50. Mat frame;
  51. for(int i=0; i<25; i++) {
  52. int fid = distribution(generator);
  53. cap.set(CAP_PROP_POS_FRAMES, fid);
  54. Mat frame;
  55. cap >> frame;
  56. if(frame.empty())
  57. continue;
  58. frames.push_back(frame);
  59. }
  60. // Calculate the median along the time axis
  61. Mat medianFrame = compute_median(frames);
  62. // Display median frame
  63. imshow("frame", medianFrame);
  64. waitKey(0);
  65. // Reset frame number to 0
  66. cap.set(CAP_PROP_POS_FRAMES, 0);
  67. // Convert background to grayscale
  68. Mat grayMedianFrame;
  69. cvtColor(medianFrame, grayMedianFrame, COLOR_BGR2GRAY);
  70. // Loop over all frames
  71. while(1) {
  72. // Read frame
  73. cap >> frame;
  74. if (frame.empty())
  75. break;
  76. // Convert current frame to grayscale
  77. cvtColor(frame, frame, COLOR_BGR2GRAY);
  78. // Calculate absolute difference of current frame and the median frame
  79. Mat dframe;
  80. absdiff(frame, grayMedianFrame, dframe);
  81. // Threshold to binarize
  82. threshold(dframe, dframe, 30, 255, THRESH_BINARY);
  83. // Display Image
  84. imshow("frame", dframe);
  85. waitKey(20);
  86. }
  87. cap.release();
  88. return 0;
  89. }