As shown, this is a video surveillance tape at a traffic junction. Each pixel in the video is a static background for most of the time, and a small amount of time is a dynamic foreground. So the image of all the frames in the video is superimposed, and then averaged, the average image will be closer to the actual background.
Code:
#include <opencv2/opencv.hpp>#include<iostream>#include<Eigen/Dense>#include<string>Cv::mat GETAVERAGEBG (cv::videocapture& Capture,intStartintend) { LongFramecount = End-start; intindex =0; intwidth = capture.Get(Cv_cap_prop_frame_width); intHeight = capture.Get(Cv_cap_prop_frame_height); Eigen::matrixxd averagebgr (height, width); Eigen::matrixxd averagebgg (height, width); Eigen::matrixxd AVERAGEBGB (height, width); for(inti =0; i < height; i++){ for(intj =0; J < width; J + +) {AVERAGEBGR (i, J)=0; Averagebgg (i, J)=0; AVERAGEBGB (i, J)=0; } } for(inti = start; I < end; i++) {Index++; //move the internal pointer to frame I of the video imageCapture.Set(Cv_cap_prop_pos_frames, i); Cv::mat Curmat; Capture.read (Curmat); for(inti =0; i < height; i++) {cv::vec3b* p = curmat.ptr<cv::vec3b>(i); for(intj =0; J < width; J + +) {AVERAGEBGR (i, J)+ = p[j][0] ; Averagebgg (i, J)+ = p[j][1] ; AVERAGEBGB (i, J)+ = p[j][2] ; }} std::cout<< index<<"/"<<framecount <<Std::endl; }//For every frameCv::mat result (HEIGHT,WIDTH,CV_8UC3); for(inti =0; i < height; i++){ for(intj =0; J < width; J + +) {cv::vec3b p; //std::cout << AVERAGEBGR (i, J) << Std::endl;p[0] = static_cast<uchar> (AVERAGEBGR (i, j)/(float) framecount); p[1] = static_cast<uchar> (Averagebgg (i, j)/(float) framecount); p[2] = static_cast<uchar> (AVERAGEBGB (i, j)/(float) framecount); result.at<cv::Vec3b> (i, j) =p; } } returnresult;}intMainintargcChar*argv[]) {Cv::videocapture capture; if(ARGC <3){ return 1; } std::stringFileName (argv[1]); STD::stringOutname (argv[2]); if(!Capture.open (FileName)) {Std::cout<<"can not open video"<<Std::endl; return 1; } LongFramecount = static_cast<Long> (Capture.Get(Cv_cap_prop_frame_count)); Cv::mat BG= GETAVERAGEBG (Capture,0, Framecount); Cv::imwrite (outname, BG); Cv::imshow ("", BG); Cv::waitkey (); return 0;}
Results:
A mechanical average image for the background code