注意事項
1)添加命名空間
using namespace cvb;
2)
// unique_ptr<IplImage, void(*)(IplImage*)> labelImg(cvCreateImage(cvSize(width, height), IPL_DEPTH_LABEL, 1),
// [](IplImage* p){ cvReleaseImage(&p); });
錯誤
無法從“`anonymous-namespace'::<lambda0>”轉換為“void (__cdecl *const )
暫時不使用C11的語言特性
3)
需要将使用的庫函數導出來,使用如下的宏定義:
__declspec(dllexport)
源碼
#include <SDKDDKVer.h>
#include <stdio.h>
#include <tchar.h>
#include<iostream>
#include "cv.h"
#include "cvblob.h"
#include "highgui.h"
#include<opencv2\opencv.hpp>
#include<opencv2\video\background_segm.hpp>
using namespace cv;
using namespace std;
//對輪廓按面積降序排序,目的是去除那些小輪廓目标
bool descSort(vector<Point> p1, vector<Point> p2) {
return contourArea(p1) > contourArea(p2);
}
void processVideo(char* videoFilename)
{
Mat frame; // current frame
Mat fgMaskMOG2; // fg mask fg mask generated by MOG2 method
Mat bgImg; // background
Ptr<BackgroundSubtractorMOG2> pMOG2 = createBackgroundSubtractorMOG2(200, 36.0, false); // MOG2 Background subtractor
while (true)
{
VideoCapture capture(videoFilename);
if (!capture.isOpened())
{
cerr << "Unable to open video file: " << videoFilename << endl;
return;
}
int width = (int)capture.get(CV_CAP_PROP_FRAME_WIDTH);
int height = (int)capture.get(CV_CAP_PROP_FRAME_HEIGHT);
IplImage* labelImg = cvCreateImage(cvSize(width, height), IPL_DEPTH_LABEL, 1);
CvBlobs blobs;
CvTracks tracks;
while (true)
// read input data. ESC or 'q' for quitting
int key = waitKey(1);
if (key == 'q' || key == 27)
return;
if (!capture.read(frame))
break;
// update background
pMOG2->apply(frame, fgMaskMOG2);
pMOG2->getBackgroundImage(bgImg);
imshow("BG", bgImg);
imshow("Original mask", fgMaskMOG2);
// post process
medianBlur(fgMaskMOG2, fgMaskMOG2, 5);
imshow("medianBlur", fgMaskMOG2);
morphologyEx(fgMaskMOG2, fgMaskMOG2, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(5, 5))); // fill black holes
morphologyEx(fgMaskMOG2, fgMaskMOG2, MORPH_OPEN, getStructuringElement(MORPH_RECT, Size(5, 5))); // fill white holes
imshow("morphologyEx", fgMaskMOG2);
// track
cvLabel(&IplImage(fgMaskMOG2), labelImg, blobs);
cvFilterByArea(blobs, 64, 10000);
cvUpdateTracks(blobs, tracks, 10, 90, 30);
cvRenderTracks(tracks, &IplImage(frame), &IplImage(frame));
// show
imshow("Frame", frame);
key = waitKey(30);
}
int main() {
processVideo("E:/smoky-cars/positive/大慶東路與水機路交叉口(東北)_冀BU0157_02_141502_01_3_50.wh264");
return 0;
//讀入視訊
VideoCapture capture("E:/smoky-cars/positive/大慶東路與水機路交叉口(東北)_冀BU0157_02_141502_01_3_50.wh264");
//定義一個Mat變量,用于存儲每一幀的圖像
Mat frame;
//前景
Mat mask;
//連通分量
Mat srcImage;
//結果
Mat result;
//用混合高斯模型訓練背景圖像
Ptr<BackgroundSubtractorMOG2> bgsubtractor = createBackgroundSubtractorMOG2();
bgsubtractor->setVarThreshold(20);
//for (int k = 0; k < 100; k++)
//{
// //讀取目前幀
// capture >> frame;
// //若視訊播放完成,退出循環
// if (frame.empty())
// {
// break;
// }
// bgsubtractor->apply(frame, mask, 0.2);
//}
//imshow("前景訓練結果", mask);
//循環顯示每一幀
//讀取目前幀
capture >> frame;
//若視訊播放完成,退出循環
if (frame.empty())
break;
frame.copyTo(result);
//cvtColor(frame, frame, COLOR_GRAY2BGR);
bgsubtractor->apply(frame, mask, 0.2);
imshow("原視訊", frame); //顯示目前幀
//waitKey(30); //延時30ms
imshow("混合高斯模組化", mask);
//waitKey(30);
//cvtColor(mask, mask, COLOR_GRAY2BGR);
//對前景先進行中值濾波,再進行形态學膨脹操作,以去除僞目标和連接配接斷開的小目标
medianBlur(mask, mask, 5);
//morphologyEx(mask, mask, MORPH_DILATE, getStructuringElement(MORPH_RECT, Size(5, 5)));
//測試:先開運算再閉運算
morphologyEx(mask, mask, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(5, 5)));
morphologyEx(mask, mask, MORPH_OPEN, getStructuringElement(MORPH_RECT, Size(5, 5)));
waitKey(30);
//拷貝
mask.copyTo(srcImage);
//各聯通分量的輪廓
//外層vector的size代表了圖像中輪廓的個數,裡面vector的 size代表了輪廓上點的個數
vector<vector<Point>> contours;
//隻擷取最外輪廓,擷取每個輪廓的每個像素,并相鄰兩個像素位置差不超過1
findContours(srcImage, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
//測試輪廓擷取
imshow("輪廓擷取", srcImage);
if (contours.size() < 1) continue;
//外接矩陣
Rect rct;
//對輪廓進行外接矩陣之前先對輪廓按面積降序排序,目的為了去除小目标(僞目标)
sort(contours.begin(), contours.end(), descSort);
for (int i = 0; i < contours.size(); i++)
//當第i個連通分量的外接矩陣面積小于最大面積的1/6,則認為是僞目标
if (contourArea(contours[i]) < contourArea(contours[0]) / 5)
//包含輪廓的最小矩陣
rct = boundingRect(contours[i]);
rectangle(result, rct, Scalar(0, 255, 0), 2);
imshow("結果", result);
getchar();
參考
http://blog.csdn.net/xfgryujk/article/details/61421763
本文轉自fengyuzaitu 51CTO部落格,原文連結:http://blog.51cto.com/fengyuzaitu/1637984,如需轉載請自行聯系原作者