基于Opencv 的移动目标检测

实现流程:

(1)利用capture函数读取视频文件,利用capture.read(frame)从视频文件当中读取出来每一帧图像frame。

(2)利用cvtColor(frame, edges, CV_BGR2GRAY)函数,将每一帧图像转化为灰度图,便于之后进行二值化处理。

(3)利用GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5)函数,对得到的灰度图进行高斯模糊,以减少图像中的干扰噪声。

(4)遍历高斯模糊后图像的每一个灰度值,对灰度值进行限制并进行二值化处理。以此减小背景对检测目标的干扰。

(5)分别调用erode(edges, edges, ele)函数和dilate(edges, edges, ele)函数,通过设定不同的参数值,对图像进行腐蚀与膨胀操作。

(6)通过findContours函数,对图像轮廓进行检测。之后遍历每一个轮廓,通过boundingRect函数,找出轮廓最小外界矩形。最后对矩形框的大小进行限制,减少检测的错误率。

(7)将得到的矩形框标注在视频中的每一帧原图像上面,并进行输出。

基于Opencv 的移动目标检测

基于Opencv 的移动目标检测

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat edges, dstImage, ele;
	vector<vector<Point>>contours;
	vector<Vec4i>hierarchy;
	VideoCapture capture("F:/Project_C++/video_detection/1.avi");	//打开视频文件
	if (!capture.isOpened())
		cout << "fail to open!" << endl;
	long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
	cout << "整个视频共" << totalFrameNumber << "帧" << endl;
	long currentFrame = 0;
	while (true)
	{
		Mat frame;
		if (!capture.read(frame))	//读取每一帧
		{
			cout << "读取视频失败" << endl;
			return -1;
		}
		currentFrame++;	//帧计数
		cout << "正在读取第" << currentFrame << "帧" << endl;
		cvtColor(frame, edges, CV_BGR2GRAY);	//转化为灰度图
		GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);	//把edges里面的图像做高斯模糊
		for (int i = 0; i<edges.rows; i++)	//阈值二值化
			for (int j = 0; j<edges.cols; j++)
				if ((edges.at<unsigned char>(i, j) < 50) && (edges.at<unsigned char>(i, j) > 40))
					edges.at<unsigned char>(i, j) = 255;
				else edges.at<unsigned char>(i, j) = 0;
		ele = getStructuringElement(MORPH_RECT, Size(3, 3));	//腐蚀操作
		erode(edges, edges, ele);
		ele = getStructuringElement(MORPH_RECT, Size(40, 60));	//膨胀操作
		dilate(edges, edges, ele);
		//imshow("读取视频", edges);

		findContours(edges, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);	//检测出轮廓
		for (int index = 0; index >= 0; index = hierarchy[index][0])
		{
			//drawContours(edges, contours, index, Scalar(255, 255, 255), FILLED, 8, hierarchy);
			Rect rect = boundingRect(contours[index]);	//找出轮廓最小外界矩形
			cout << "矩形框" << rect.width << endl;
			if((rect.width > 180) && (rect.width < 400) && (rect.height < 600) && (rect.height > 400))	//限定矩形框的大小
				rectangle(frame, rect, Scalar(0, 0, 255), 3);	//在原图像上画出矩形
			imshow("读取视频", frame);	//显示每一帧
		}
		waitKey(30);
	}
	capture.release();
	return 0;
}