OpenCV动态人物识别代码

动态人物识别代码


int main()
{
	// 打开视频文件或摄像头
	VideoCapture cap("vtest.avi");
	// VideoCapture cap(0);  // 使用默认摄像头

	if (!cap.isOpened())
	{
		std::cout << "无法打开视频文件或摄像头流" << std::endl;
		return -1;
	}

	// 读取第一帧
	Mat prevFrame,prevGray;
	cap >> prevFrame;

	prevGray = Mat(prevFrame.size(), CV_8UC1, Scalar(255));
	int kk = 0;
	while (true)
	{
		Mat nextFrame, nextGray;
		cap >> nextFrame;

		if (nextFrame.empty())
			break;

		// 将当前帧与背景帧进行差分
		Mat diff;
		absdiff(prevFrame, nextFrame, diff);

		// 将差分图像转换为灰度图像
		Mat gray;
		cvtColor(diff, gray, COLOR_BGR2GRAY);

		GaussianBlur(gray, gray, Size(9, 9), 2, 2);  //平滑滤波
		// 对灰度图像进行阈值处理
		threshold(gray, nextGray, 30, 255, THRESH_BINARY);
		
		//当前二值化图像  --  (上一张和当前图像的二值化图像) 与 (下一张和当前图像的二值化图像)
		Mat currentGray;
		bitwise_and(prevGray, nextGray, currentGray);

		// 对二值图像进行膨胀操作,以填充物体区域
		Mat dilated;
		Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
		dilate(currentGray, dilated, kernel, Point(-1, -1), 3);

		//生成随机颜色,用于区分不同连通域
		RNG rng(10086);
		Mat out, stats, centroids;
		//统计图像中连通域的个数
		int number = connectedComponentsWithStats(dilated, out, stats, centroids, 8, CV_16U);
		vector<Vec3b> colors;
		for (int i = 0; i < number; i++)
		{
			//使用均匀分布的随机数确定颜色
			Vec3b vec3 = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
			colors.push_back(vec3);
		}

		//以不同颜色标记出不同的连通域
		Mat result = Mat::zeros(prevFrame.size(), CV_8UC3);
		int w = result.cols;
		int h = result.rows;
		for (int i = 1; i < number; i++)
		{
			// 中心位置
			int center_x = centroids.at<double>(i, 0);
			int center_y = centroids.at<double>(i, 1);
			//矩形边框
			int x = stats.at<int>(i, CC_STAT_LEFT);
			int y = stats.at<int>(i, CC_STAT_TOP);
			int w = stats.at<int>(i, CC_STAT_WIDTH);
			int h = stats.at<int>(i, CC_STAT_HEIGHT);
			int area = stats.at<int>(i, CC_STAT_AREA);
			if (area < 500)
			{
				continue;
			}
			// 外接矩形
			Rect rect(x, y, w, h);
			rectangle(prevFrame, rect, colors[i],2);

		}
		// 寻找轮廓
		//std::vector<std::vector<Point>> contours;
		//std::vector<Vec4i> hierarchy;
		//findContours(dilated, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

		// 绘制检测到的轮廓
		//for (size_t i = 0; i < contours.size(); i++)
		//{
		//	if (minAreaRect(contours[i]).boundingRect().area()< 500)  // 设置最小轮廓面积以过滤噪声
		//		continue;
		//	Rect boundingRect1 = boundingRect(contours[i]);
		//	rectangle(prevFrame, boundingRect1, Scalar(0, 255, 0), 2);
		//}
		// 显示结果帧
		imshow("Motion Detection", prevFrame);

		// 按下ESC键退出循环
		if (waitKey(1) == 27)
			break;

		//用作下一个循环做对比
		prevGray = nextGray;
		prevFrame = nextFrame;
	}

	// 释放资源并关闭窗口
	cap.release();
	destroyAllWindows();

	return 0;
}

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值