第17课 为rtsp流加入移动检测功能

33 篇文章 2 订阅
31 篇文章 3 订阅

在上节课,我们成功拿到了rtsp视频和音频流,在第13课,我们为普通的usb摄像头加上了移动检测功能,那能不能给rtsp摄像头也加上移动检测功能以实现一些好玩的应用呢?答案是肯定的,在usb摄像头检测中,我们把关键的视频画面数据转化为Mat进行比较处理,在rtsp流的播放中,我们同样是把视频画面数据转化为Mat进行显示,两者都是将图像数据转为Mat进行处理。将图像数据统一转为Mat,可以借助openCV的强大功能对图像进行各种操作,这也是这套教程为什么要基于FFmpeg+openCV进行开发的主要原因。因此,我们只需usb摄像头检测功能移植过来就能实现对rtsp摄像头的移动检测了。

1.备份demo16并修改demo16为demo17.

2.移植demo13中的检测代码到本工程视频解码部分:

if (normalPkt.stream_index == videoIndex)
		{
			ret = avcodec_send_packet(vDecodeCtx, &normalPkt);
			ret = avcodec_receive_frame(vDecodeCtx, deVideoFrame);
			av_packet_unref(&normalPkt);
			ret = sws_scale(bgrSwsCtx, (const uint8_t* const*)deVideoFrame->data, deVideoFrame->linesize, 0, deVideoFrame->height, bgrFrame.data, bgrFrame.linesize);
			srcMat = cv::Mat(bgrFrame.height, bgrFrame.width, CV_8UC3, bgrFrame.data[0]);
			//imshow("video", srcMat);
			//cv::waitKey(10);
			mainDlg->drawMatOfPlay(srcMat);
			av_frame_unref(deVideoFrame);


			//比较旧图像与新图像
			if (!oldMat.empty() && !srcMat.empty()){		
			
				cv::Mat diff, gray, blurred, thresholded, dilated;
				//计算两帧图像的差异
				cv::absdiff(oldMat, srcMat, diff); 
				//转换为灰度图像
				cv::cvtColor(diff, gray, cv::COLOR_BGR2GRAY); 
				//高斯模糊
				cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0); 
				//二值化
				cv::threshold(blurred, thresholded, 20, 255, cv::THRESH_BINARY); 				
				//膨胀
				cv::dilate(thresholded, dilated, cv::Mat(), cv::Point(-1, -1), 2); 
				//查找轮廓
				std::vector<std::vector<cv::Point>> contours;
				cv::findContours(dilated, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); 
				bool objectMoved = false;
				for (const auto& contour : contours)
				{
					double area = cv::contourArea(contour);
					//设置最小轮廓面积阈值
					if (area > 1000) 
					{
						objectMoved = true;
						break;
					}
				}

				if (objectMoved)
				{
					TRACE("您已进行监控区域...\n");
					//cv::putText(dilated, "Moving... ", cv::Point(0, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
					//播放广告语或叠加透明视频
				}
				else
				{
					//cv::putText(dilated, "Stopping... ", cv::Point(0, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
					TRACE("物体未移动\n");
				}
			
			}


			//缓存上一帧图像
			oldMat = srcMat.clone();

		}

3.调试运行,当有行人或光线引起较大面积变化时会提示有物体移动,我们可以在此基础上进一步完善以实现自己想要的功能。

4.思考并继续优化

通过调试实际运行,我们发现检测画面有时会滞后于实时画面,这是怎么回事呢,该如何解决呢?感兴趣的同学好好思考一下尝试自己解决一下吧。

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西部秋虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值