传统运动目标检测算法——帧差法、光流法、背景减除法

1.运动目标检测

运动目标检测(Motion Object Detection)是计算机视觉和图像处理领域的一个重要任务,旨在从视频或图像序列中检测并跟踪移动的目标对象。这些目标对象可以是人、车辆、动物或其他物体,而运动目标检测的目标是准确定位、跟踪和分割这些目标,以了解它们在视频帧或图像序列中的位置、大小、形状和运动状态。这其中就包括前景检测,前景检测旨在将视频或图像序列中的前景(即移动的目标)与背景分离。这通常采用侦查法、光流法以及背景减除法,以识别前景像素。

1.1 帧差法

帧差法,顾名思义就是利用视频或图像序列中相邻的两帧或者三帧的像素灰度差值并通过选定的灰度阈值进而提取视频或图像序列中的前景目标。帧差法算法简单容易实现,时间复杂度较低而且对快速移动的目标非常敏感,这使得的它在检测快速物体的场景中非常有效。虽然帧差法有这些优点,但是也存在以下的缺点,对光照变化敏感,容易受到背景的干扰,难以处理遮挡等。帧差法主要有两帧差法和三帧差法。
两帧差法工作原理:

  1. 选择视频或图像序列中连续的两帧图像,我们分别用 t 时刻的图像帧减去 t-1时刻的图像帧得到两帧的差值,然后利用阈值过滤以提高获得的信号质量,具体由下式确定:

P f ( x , y ) = ∣ L f ( x , y ) − L f − 1 ( x , y ) ∣ \begin{equation} P_{f}(x, y) =| L_{f}(x, y) - L_{f-1}(x, y) |\tag{1} \end{equation} Pf(x,y)=Lf(x,y)Lf1(x,y)(1)

P ~ f = { P f ( x , y ) , i f P f ( x , y ) ≥ T p 0 , O t h e r w i s e (2) \tilde{P} _{f} = \begin{cases} P_{f}(x, y), & ifP_{f}(x, y) \geq T_{p}\\ 0,& Otherwise\\ \end{cases} \tag{2} P~f={Pf(x,y),0,ifPf(x,y)TpOtherwise(2)

其中, 公式(1)中   P f ( x , y )   \ P_{f}(x, y)\,  Pf(x,y) 是两帧的图像的差值的绝对值,在公式(2)中   P ~ f ( x , y )   \ \tilde{P}_{f}(x, y)\,  P~f(x,y)根据公式(1)得到的值进行过滤处理,大于阈值的值保持不变,小于阈值的值进行归零处理 。两帧图像之间的像素差异超过了一个预定的阈值,那么这些差异点被认为表示了目标的运动。同样三帧差分法的处理过程大同小异,其中需要对利用两帧差分法得到的两帧图像的像素进行与运算。
在这里插入图片描述

图1 左利用两帧差法, 右利用三帧差法
从图中我们可以看出划分出来的前景人物像素并不连贯,可以考虑利用形态学的操作填充小的孔洞并关闭目标物体。

完整代码

#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

#define PATH "D://VS_Project//image//Crowd-Activity-All.avi"
int twoFrameDifference();
int threeFrameDifference();
int main()
{
	//int k = twoFrameDifference();// 两帧差法
	int l = threeFrameDifference();// 三帧差法
	return 0;
}
int twoFrameDifference() // 两帧差法
{
	cv::VideoCapture cap(PATH);
	if (!cap.isOpened()) {
		std::cerr << "无法打开视频文件" << std::endl;
		return -1;
	}
	cv::Mat prevFrame, currentFrame;
	while (true) {
		cap >> currentFrame;
		if (currentFrame.empty())break;
		cv::cvtColor(currentFrame, currentFrame, cv::COLOR_BGR2GRAY);
		if (!prevFrame.empty()) {
			cv::Mat P;
			cv::absdiff(currentFrame, prevFrame, P);
			cv::threshold(P, P, 10, 255, THRESH_BINARY);
			cv::imshow("P", P);
			cv::waitKey(1000 / cap.get(CV_CAP_PROP_FPS));
		}
		prevFrame = currentFrame.clone();
	}
	cap.release();
	cv::destroyAllWindows();
	return 0;
}
int threeFrameDifference()
{
	cv::VideoCapture cap(PATH);
	if (!cap.isOpened()) {
		std::cerr << "无法打开视频文件" << std::endl;
		return -1;
	}
	cv::Mat prevFrame, currentFrame, lastFrame;
	while (true) {
		cap >> currentFrame;
		if (currentFrame.empty())break;
		cv::cvtColor(currentFrame, currentFrame, cv::COLOR_BGR2GRAY);
		if (!prevFrame.empty() && !lastFrame.empty()) {
			cv::Mat P;
			cv::absdiff(currentFrame, prevFrame, P);
			cv::Mat P2;
			cv::absdiff(prevFrame, lastFrame, P2);
			cv::bitwise_and(P, P2, P);
			cv::threshold(P, P, 10, 255, THRESH_BINARY);
			cv::imshow("P", P);
			cv::waitKey(1000 / cap.get(CV_CAP_PROP_FPS));
		}
		lastFrame = prevFrame.clone();
		prevFrame = currentFrame.clone();
	}
	cap.release();
	cv::destroyAllWindows();
	return 0;
}


1.2 光流法

1.2.1 光流和光流场

光流是空间运动物体在观测成像面上的像素运动的瞬时速度。 光流的研究是利用图像序列中的像素强度数据的时域变化和相关性来确定各自像素位置的“运动”,即研究图像灰度在时间上的变化与景象中物体结构及其运动的关系。将二维图像平面特定坐标点上的灰度瞬时变化率定义为光流矢量。
在这里插入图片描述

上图显示一个球在连续 5 帧中移动。箭头显示其位移矢量。

光流场(optical flow field)是指图像灰度模式的表观运动。它是一个二维矢量场,它包含的信息即是各像点的瞬时运动速度矢量信息。研究光流场的目的就是为了从序列图像中近似计算不能直接得到的运动场。

光流法的主要目标是分析连续帧之间的像素位移,以获取物体、相机或观察者的运动模式。 这项技术在许多领域中都有广泛的应用,包括目标跟踪、运动分析、结构重建、自动驾驶等。光流法有多种变体和实现方法,包括稀疏光流和稠密光流。这些方法可以应用于不同类型的问题,如移动目标跟踪、相机位移估算、行人检测等。

在这里插入图片描述
左图表示稀疏光流,它跟踪有限数量的“特征”像素,而右图显示密集光流,它估计图像中所有像素的流。

1.2.1 光流原理

光流基于以下两个假设:

  1. 亮度恒定不变假设,这个假设的核心思想是移动物体同一点在不同帧之间的亮度保持不变。
  2. 领域光流相似假设
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值