数字图像处理项目:背景建模跟踪目标(提取轮廓显示矩形框)

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

//针处理函数
void processFrame(Mat& binary, vector<Rect>& rect);

int main(int argc, char**) {
	VideoCapture capture;
	capture.open("video_003.avi");
	if (!capture.isOpened()) {
		printf("could not find the video file...\n");
		return -1;
	}
	int frame_count = capture.get(CAP_PROP_FRAME_COUNT);
	int fps = capture.get(CAP_PROP_FPS);
	cout << frame_count << endl;
	cout << fps << endl;
	// create windows
	Mat frame;
	Mat bsmaskMOG2, bsmaskKNN;
	namedWindow("input video", WINDOW_AUTOSIZE);
	namedWindow("MOG2", WINDOW_AUTOSIZE);
	namedWindow("KNN Model", WINDOW_AUTOSIZE);
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	Mat kernel2 = getStructuringElement(MORPH_ELLIPSE, Size(3, 3), Point(-1, -1));
	// intialization BS
	Ptr<BackgroundSubtractor> pMOG2 = createBackgroundSubtractorMOG2();
	/*
	Ptr<backgroundsubtractormog2>
	cv::createBackgroundSubtractorMOG2  (
						int     history = 500,  //用于训练背景的帧数,默认为500帧,如果不手动设置learningRate
						,history就被用于计算当前的learningRate,此时history越大,learningRate越小,背景更新越慢;
						double  varThreshold = 16,  //方差阈值,用于判断当前像素是前景还是背景。一般默认16
						,如果光照变化明显,如阳光下的水面,建议设为25,36,具体去试一下也不是很麻烦,值越大,灵敏度越低;
						bool    detectShadows = true   //是否检测影子,设为true为检测,false为不检测,
						检测影子会增加程序时间复杂度,如无特殊要求,建议设为false;
)
	*/
	Ptr<BackgroundSubtractor> pKNN = createBackgroundSubtractorKNN();
	while (capture.read(frame)) {
		vector<Rect> rect;
		
		// MOG BS
		pMOG2->apply(frame, bsmaskMOG2);
		/*
		virtual void cv::BackgroundSubtractor::apply    (
				InputArray  image,		//image 源图
				OutputArray     fgmask,  //fmask 前景(二值图像)
				double  learningRate = -1   //learningRate 学习速率,
				,值为0-1,为0时背景不更新,为1时逐帧更新,默认为-1,即算法自动更新
				)
		*/
		morphologyEx(bsmaskMOG2, bsmaskMOG2, MORPH_OPEN, kernel, Point(-1, -1));
		//dilate(bsmaskMOG2, bsmaskMOG2, kernel2, Point(-1, -1), 2);// 膨胀
		
	
		imshow("MOG2", bsmaskMOG2);

		// KNN BS mask
		// 最后一个参数 (0-1之间表示学习背景模型时长,-1表示opencv自动设置学习时长
		//,0表示不更改背景模型,1表示背景模型按照最后一帧重新初始化)
		pKNN->apply(frame, bsmaskKNN, -1);
		imshow("KNN Model", bsmaskKNN);
		morphologyEx(bsmaskKNN, bsmaskKNN, MORPH_OPEN, kernel2, Point(-1, -1));
		dilate(bsmaskKNN, bsmaskKNN, kernel2, Point(-1, -1), 4);// 膨胀
		//处理bsmaskKNN二值化图像
		processFrame(bsmaskMOG2, rect);
		for (int j = 0; j < rect.size(); j++)
		{
			rectangle(frame, rect[j], Scalar(0, 0, 255), 2, 8);
		}
		imshow("input video", frame);
		char c = waitKey(100);
		if (c == 27) {
			break;
		}
	}
	capture.release();
	waitKey(0);
	return 0;
}

void processFrame(Mat& binary, vector<Rect>& rect) {
	vector<vector<Point>> contours;
	vector<Vec4i> hireachy;
	findContours(binary, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
	int num = contours.size();
	for (int i = 0; i < num; i++)
	{
		int num_points = contours[i].size();
		if (num_points > 20)
		{
			Rect point_rect = boundingRect(contours[i]);
			rect.push_back(point_rect);
		}
	}

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,可以使用OpenCV库来完成这个任务。首先,我们需要读入一张图片,并将其转换为HSV色彩空间。 ```python import cv2 import numpy as np # 读入图片 img = cv2.imread('image.jpg') # 将图片转换为HSV色彩空间 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) ``` 接下来,我们需要定义红色的颜色范围,用于过滤出图片中的红色部分。 ```python # 定义红色颜色范围 lower_red = np.array([0, 50, 50]) upper_red = np.array([10, 255, 255]) lower_red2 = np.array([160, 50, 50]) upper_red2 = np.array([180, 255, 255]) # 过滤出红色部分 mask_red1 = cv2.inRange(hsv, lower_red, upper_red) mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2) mask_red = cv2.bitwise_or(mask_red1, mask_red2) ``` 然后,我们可以使用形态学操作,如腐蚀和膨胀,来去除噪点和连接断开的部分。 ```python # 进行形态学操作 kernel = np.ones((5,5), np.uint8) mask_red = cv2.erode(mask_red, kernel) mask_red = cv2.dilate(mask_red, kernel) ``` 接着,我们可以使用轮廓检测函数`cv2.findContours()`来获取红色部分的轮廓。 ```python # 获取红色部分的轮廓 contours, _ = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ``` 最后,我们可以遍历轮廓,找到最大的红色轮廓,并用矩形框选它。 ```python # 找到最大的红色轮廓 max_contour = max(contours, key=cv2.contourArea) # 获取矩形框坐标 x, y, w, h = cv2.boundingRect(max_contour) # 在图片上绘制矩形框 cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2) # 显示图片 cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 完整代码如下: ```python import cv2 import numpy as np # 读入图片 img = cv2.imread('image.jpg') # 将图片转换为HSV色彩空间 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 定义红色颜色范围 lower_red = np.array([0, 50, 50]) upper_red = np.array([10, 255, 255]) lower_red2 = np.array([160, 50, 50]) upper_red2 = np.array([180, 255, 255]) # 过滤出红色部分 mask_red1 = cv2.inRange(hsv, lower_red, upper_red) mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2) mask_red = cv2.bitwise_or(mask_red1, mask_red2) # 进行形态学操作 kernel = np.ones((5,5), np.uint8) mask_red = cv2.erode(mask_red, kernel) mask_red = cv2.dilate(mask_red, kernel) # 获取红色部分的轮廓 contours, _ = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 找到最大的红色轮廓 max_contour = max(contours, key=cv2.contourArea) # 获取矩形框坐标 x, y, w, h = cv2.boundingRect(max_contour) # 在图片上绘制矩形框 cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2) # 显示图片 cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值