opencv学习笔记四十四:移动对象统计

步骤:

  1. 利用背景消除法找到移动的物体;
  2. 预处理:进行中值滤波消除椒盐噪声,然后二值化再开操作;
  3. 寻找轮廓;
  4. 画出轮廓最小矩形并统计。
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main(int arc, char** argv) { 
	VideoCapture capture;
	capture.open("vtest.avi");
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	namedWindow("motion objects", CV_WINDOW_AUTOSIZE);
	Mat frame,mogMask;
	//实例化背景消除法模型
	Ptr<BackgroundSubtractorMOG2>mog2 = createBackgroundSubtractorMOG2();
	//定义结构元素
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
	//定义发现的轮廓
	vector<vector<Point>>contours;
	//层次
	vector<Vec4i>hierarchy;
	int count = 0;
	//定义字符数组
	char numText[2];

	while (capture.read(frame)) {
		imshow("input", frame);
		//应用混合高斯模型去除背景
		mog2->apply(frame, mogMask);
		//中值滤波
		medianBlur(mogMask, mogMask, 3);
		//得到的结果为灰度图像,对其进行二值化
		threshold(mogMask, mogMask, 100, 255, THRESH_BINARY);
		//开操作
		morphologyEx(mogMask, mogMask, MORPH_OPEN, kernel);
		//寻找最外层轮廓
		findContours(mogMask, contours, hierarchy, 0, CHAIN_APPROX_SIMPLE, Point(0, 0));
		count = 0;
		for (int i = 0; i < contours.size(); i++) {
			//drawContours(frame, contours, i, Scalar(255, 0, 0));
			double area = contourArea(contours[i]);
			if (area < 1000)continue;//去掉面积小于1000的轮廓
			Rect selection = boundingRect(contours[i]);
			if (selection.width < 30 || selection.height < 30)continue;//去掉明显不符合被检测物体形状的轮廓
			count++;
			rectangle(frame, selection, Scalar(0, 0, 255), 2);
			//sprintf和平时我们常用的printf函数的功能很相似。sprintf函数打印到字符串中,而printf函数打印输出到屏幕上
			sprintf_s(numText, "%d", count);
			putText(frame, numText, Point(selection.x, selection.y), CV_FONT_NORMAL, FONT_HERSHEY_PLAIN,Scalar(0,255,0), 1);
		}


		imshow("motion objects", frame);
		char c = waitKey(100);
		if (c == 27) { break; }
	}
	capture.release();
	waitKey(0);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_24946843/article/details/82747714