实用小程序:
//opencv2.0风格 //本程序有几个可调值 //1.背景更新 学习率 learningRate //2.去掉小面积阈值 area_threshold #include "cv.h" #include "highgui.h" #include <stdlib.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <iostream> #include <string> #include <cstdio> using namespace std; using namespace cv; char input_name[50]; char outFolder[50]; char countChar[10000]; char tmp[50]; int main() { //可调参数 //char* input_name = "007.avi"; double fScale = 0.5; //缩放倍数 double learningRate=0.5; // 控制背景累积学习的速率 double area_threshold = 30; //区域面积大小阈值 int nThreshold=30; //二值化阈值 Mat frame_ori; //每一帧原图像,绝不处理 Mat frame; //每一帧图像处理 Mat gray; //frame转成的灰度图 Mat frame_copy_8U; //copy过来的8U图像 Mat frame_copy; Mat img1; //差分输出 Mat outBinary; //二值图输出 //输入 cout<<"please input the src video :"<<endl; cin>>input_name; cout<<"please input the output folder :"<<endl; cin>>outFolder; //从视频读入 VideoCapture capture(input_name); int count=0; if(capture.isOpened()/*capture*/) //读取文件开关 { //对每一帧做处理 for(;;) { //单帧处理 capture >> frame_ori; if(!frame_ori.empty())//如果捕捉到了 { cout<<"\n\n***************New Start********************"<<endl; //将原图像缩放 //resize(frame_ori,frame,Size(frame_ori.cols * fScale,frame_ori.rows * fScale),0,0,CV_INTER_LINEAR); frame=frame_ori; //frame->gray 单通道灰度图 cvtColor(frame, gray, CV_BGR2GRAY); //进行处理 if (frame_copy.empty()) { //记录第一帧 gray->frame_copy gray.convertTo(frame_copy, CV_32F); } frame_copy.convertTo(frame_copy_8U, CV_8U); //差分 absdiff(frame_copy_8U, gray, img1); //二值化 threshold(img1, outBinary, nThreshold, 255, THRESH_BINARY); accumulateWeighted(gray, frame_copy,learningRate,outBinary); //加一个中值滤波,会减少不少误差 cv::medianBlur(outBinary, outBinary,3); //轮廓检测 vector<vector<Point>> _contours;//储存所有轮廓 vector<Vec4i>hierarchy; Mat imageROI;; cv::findContours( outBinary, _contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); int contoursSize=0; for(size_t i = 0; i< _contours.size(); ++i) { //遍历所有轮廓 //计算轮廓面积 double contArea = fabs(contourArea(_contours[i])); //去除较小面积的轮廓 if( contArea < area_threshold) continue; //获得外接矩形 Rect r0 = boundingRect(Mat(_contours[i])); //实时画出每个矩形 rectangle(outBinary,r0,cvScalar(255,255,255),1,8,0); contoursSize++; } cout<<"轮廓数 == "<<contoursSize<<endl; if(contoursSize!=0) { strcpy(countChar,outFolder); strcat(countChar,"\\"); //cout<<countChar<<endl; //cout<<"有了有了!!!!!!!!"<<endl; count++; itoa(count,tmp,10); strcat(tmp,".jpg"); strcat(countChar,tmp); //cout<<countChar<<endl; imwrite(countChar,frame_ori); } imshow("src", frame); imshow("outBinary", outBinary); } else { printf(" --(!) No captured frame -- Break!"); break; } //10ms中按任意键进入此if块 if( cvWaitKey( 10 ) >= 0 ) break; } } return 0; }