opencv实践项目-帧差法动目标识别

1.基本步骤

  • 灰度处理
  • 帧差处理
  • 二值化处理
  • 图像降噪
  • 提取关键点
  • 绘制识别框

2. 实现

代码

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <vector>

using namespace std;
using namespace cv;

void MoveObjDetect(cv::Mat& frontFrame, cv::Mat& afterFrame, std::vector<cv::Rect>& detectResult)
{
    
    
	cv::Mat diff;

	//1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
	Mat frontGray, afterGray;
	cv::cvtColor(frontFrame, frontGray, CV_RGB2GRAY);
	cv::cvtColor(afterFrame, afterGray, CV_RGB2GRAY);

	//imshow("frontGray",frontGray);
	//imshow("afterGray",afterGray);

	//2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
	cv::absdiff(frontGray, afterGray, diff);
	//imshow("diff",diff);

	//3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
	cv::threshold(diff, diff, 25, 255, CV_THRESH_BINARY);
	//imshow("threshold",diff);

	//4 图像降噪
	//4-1 腐蚀处理 目的 去除白色噪点
	Mat element = cv::getStructuringElement(MORPH_RECT, Size(1, 1));//小于3*3方块的白色噪点都会被腐蚀
	cv::erode(diff, diff, element);
	imshow("erode",diff);

	//4-2 膨胀 目的 把白色区域变大
	Mat element2 = cv::getStructuringElement(MORPH_RECT, Size(20, 20));
	cv::dilate(diff, diff, element2);
	//imshow("dilate",diff);

	//5 提取关键点
	//5-1 查找特征点
	std::vector<std::vector<cv::Point>> contours;
	std::vector<cv::Vec4i> hierarchy;
	cv::findContours(diff, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());

	//5-2 提取关键点
	//5-3 确定下四个点来用于框选目标物体
	int num = contours.size();
	for (int i = 0; i < num; i++)
	{
    
    
		vector<cv::Point> c_poly(contours[i].size());
		cv::approxPolyDP(Mat(contours[i]), c_poly, 3, true);

		//多边拟合
		cv::Rect rect;
		rect = cv::boundingRect(Mat(c_poly));

		detectResult.push_back(rect);
	}
}

int main()
{
    
    
	cv::VideoCapture capture("rtsp://192.168.6.27/0/0/0");
	cv::Mat img;
	int rate = capture.get(CV_CAP_PROP_FPS);
	int delay = 1000 / rate;
	cv::Mat lastFrame;
	cv::namedWindow("img", WINDOW_NORMAL);
	
	while (true) {
    
    
		bool ret = capture.read(img);
		if (!ret) {
    
    
			std::cout << "read video failed" << std::endl;
			break;
		}
		//动目标检测
		if (lastFrame.empty()) lastFrame = img.clone();
		std::vector<cv::Rect> detectResult;
		MoveObjDetect(lastFrame, img, detectResult);
		lastFrame = img.clone();
		//绘制识别框
		for (auto& rect : detectResult)
		{
    
    
			//绘制矩形
			cv::rectangle(img, cv::Point(rect.x, rect.y), cv::Point(rect.x + rect.width,
				(rect.y + rect.height)), cv::Scalar(0, 255, 0), 2);
		}
		cv::imshow("img", img);
		cv::waitKey(delay);

		if (!capture.grab())
		{
    
    
			break;
		}
	}
	capture.release();
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wyw0000/article/details/130098202