关注我,并留言,不定期送各种c++资料 代码全部在下面,就一个文件,随便添加一个空项目后就可以将下面代码替换到工程中。具体操作步骤没时间过多的写,可以看注释。代码运行没有问题,我用的是opencv344和vs2017。需要源代码和资料的请在这里下载,在我的工程里面环境已经配置好https://download.csdn.net/download/qq_41476542/14046884 代码如下:
#include<iostream> #include<opencv2/opencv.hpp> #include <sstream> using namespace std;//命名空间std using namespace cv;//命名空间cvv b string int2str(const int &int_temp)//数据流之间的转换 { stringstream stream;//通过流来实现字符串和数字的转换 string string_temp;//有不限长度的优点 stream << int_temp; //将int输入流,向左移4位 string_temp = stream.str(); //此处也可以用 stream>>string_temp//从stream中抽取前面插入的int值 return string_temp; } int main(int argc, const char** argv) { VideoCapture cap;//打开摄像头对象 bool update_bg_model = true; cap.open(0); // cap.open("http://113.57.246.23:8080/shot.jpg"); cap.open("C:\\Users\\Administrator\\Desktop\\acvis09-5950.avi"); //cap.open("D:\\qq\\demo\\vtest.avi"); if (!cap.isOpened()) { printf("can not open camera or video file\n"); return -1; } namedWindow("image", WINDOW_AUTOSIZE); namedWindow("foreground mask", WINDOW_AUTOSIZE);//保持原图大小 namedWindow("foreground image", WINDOW_AUTOSIZE);// namedWindow("mean background image", WINDOW_AUTOSIZE);//原图大小 Ptr<BackgroundSubtractorMOG2> bg_model = createBackgroundSubtractorMOG2();//(100, 3, 0.3, 5);建立背景模型 Mat img, fgmask, fgimg;//定义矩阵 int i = 0; for (;;)//死循环 { i++; cap >> img;//由capture类输出图像 if (img.empty()) break; img = img(Rect(40, 0, 300, img.rows)); if (fgimg.empty()) fgimg.create(img.size(), img.type()); //更新模型 bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);//背景模型的跟新 medianBlur(fgmask, fgmask, 13);//有效抑制噪声的中值滤波函数,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值。输入图像输出图像尺寸大小,必须是大于1的奇数,如3、5、7…… threshold(fgmask, fgmask, 150, 255, THRESH_BINARY);//# 阈值化,将非纯白色(244~255)的所有像素设为0 Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));// # 为了使效果更好,进行一次膨胀 /*erode(fgmask, fgmask, element, Point(0, 0), 3); dilate(fgmask, fgmask, element, Point(0, 0), 3);*/ Mat srcGrayImage = fgmask.clone(); vector<vector<Point>> vContours; vector<Vec4i> vHierarchy; // # 检测轮廓 findContours(srcGrayImage, vContours, vHierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE, Point(0, 0)); int count = 0; RNG rng(12345);//构造方法设定一个具体值,表示下面代码每次生成的结果都是一样的 for (int i = 0; i < vContours.size(); i++) { double area = contourArea(vContours[i], false); //RotatedRect该类表示平面上的旋转矩形,该类对象有三个重要属性: //矩形中心点(质心),边长(长和宽),旋转角度。三种构造函数和三种成员操作函数 RotatedRect smallRect = minAreaRect(vContours[i]); /* RotatedRect该类表示平面上的旋转矩形,有三个属性: 矩形中心点(质心) 边长(长和宽) 旋转角度 */ Point2f smallRect_center = smallRect.center; float smallRect_width = smallRect.size.width; float smallRect_height = smallRect.size.height; float smallRect_angle = 0; smallRect = RotatedRect(smallRect_center, Size2f(smallRect_height, smallRect_width), smallRect_angle); //若使用Point2f,这里就使用flow1_at_point.x形式存取像素值 Point2f P[4]; //points()函数用于求矩形的4个顶点, smallRect.points(P); if (area>600 && area < 3000) { count++; for (int j = 0; j <= 3; j++) { //划线,绘制在img上 line(img, P[j], P[(j + 1) % 4], Scalar(255, 0, 0), 2); } } if (area>3000&& area < 5000) { count += 2; for (int j = 0; j <= 3; j++) { line(img, P[j], P[(j + 1) % 4], Scalar(255, 0, 0), 2); } } } //任意值 //数数的颜色 Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); //写字参数1:, Mat& img,待写字的图片,我们写在img图上 /*参数2:,const string& text,待写入的字,我们下面写入Hello 参数3:, Point org, 第一个字符左下角坐标,我们设定在图片的Point(50, 60)坐标。表示x = 50, y = 60。 参数4:,int fontFace,字体类型,FONT_HERSHEY_SIMPLEX ,FONT_HERSHEY_PLAIN ,FONT_HERSHEY_DUPLEX 等等等。 参数5:,double fontScale,字体大小,我们设置为2号 参数6:,Scalar color,字体颜色,颜色用Scalar()表示,不懂得去百度。 参数7:, int thickness,字体粗细,我们下面代码使用的是4号 参数8:, int lineType,线型,我们使用默认值8.*/ putText(img, int2str(count), Point(220, 40), FONT_HERSHEY_TRIPLEX, 1, color, 2); //设定所有的值为0. 得到前景 fgimg = Scalar::all(0); img.copyTo(fgimg, fgmask); Mat bgimg; 得到背景 bg_model->getBackgroundImage(bgimg);//? imshow("image", img); /*string windows_name = "Video/image_" + int2str(i); string windows_name_ext = windows_name + ".jpg"; imwrite(windows_name_ext, img);*/ imshow("foreground mask", fgmask); imshow("foreground image", fgimg); //是否图像读入 if (!bgimg.empty()) imshow("mean background image", bgimg); char k = (char)waitKey(1); if (k == 27) break; if (k == ' ') { update_bg_model = !update_bg_model; if (update_bg_model) printf("\t>背景更新(Background update)已打开\n"); else printf("\t>背景更新(Background update)已关闭\n"); } } return 0; }