opencv學習筆記四十四:移動物件統計

東城青年發表於2018-09-17

步驟:

  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;
}

相關文章