opencv學習筆記四十四:移動物件統計
阿新 • • 發佈:2018-12-10
步驟:
- 利用背景消除法找到移動的物體;
- 預處理:進行中值濾波消除椒鹽噪聲,然後二值化再開操作;
- 尋找輪廓;
- 畫出輪廓最小矩形並統計。
#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; }