视频质量诊断--画面抖动的检测

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bemy1008/article/details/86687793

最近接触视频诊断,打算参考前辈们的文献资料,实现一个专题。
先从画面抖动检测开始吧。

1、画面抖动(晃动)的定义
视频采集设备由于受到外力的干扰,导致画面出现规律性的上下、左右、或上下左右的抖动,影响视觉效果。
2、抖动检测算法一般采用图像灰度投影算法、特征点匹配、图像块匹配、LK光流法等,每种算法都有优缺点,本文主要实现第一种图像灰度投影
3、算法原理介绍
在这里插入图片描述
在这里插入图片描述
4、代码实现
废话不说,别人都是只介绍原理,不上代码。我偏不!

//行投影求和
void Row_sum(Mat src, vector<int> &rowsum, float &meanR)
{
	float RS = 0;
	for (int i = 0; i < src.rows;i++)
	{
		uchar *ptr = src.ptr<uchar>(i);
		int Rsum = 0;
		for (int j = 0; j < src.cols;j++)
		{
			Rsum += ptr[j];
		}
		RS += Rsum;
		rowsum.push_back(Rsum);
	}
	meanR = RS / src.rows;
}
//列向投影求和
void Col_sum(Mat src, vector<int> &rowsum, float &meanC)
{
	float CS = 0;
	for (int i = 0; i < src.cols; i++)
	{
		int Csum = 0;
		for (int j = 0; j < src.rows; j++)
		{
			uchar *ptr = src.ptr<uchar>(j);
			Csum += ptr[i];
		}
		CS += Csum;
		rowsum.push_back(Csum);
	}
	meanC = CS / src.cols;
}
//计算互相关最小值
void Cal_min(vector<int> Crt, vector<int> Ref, int m, int &minL)
{
	int Idx = 0;
	float minV = 999999999999;
	for (int w = 1; w <= 2 * m + 1;w++)
	{
		float sum_Diff = 0;
		for (int i = 0; i < Crt.size()-2*m; i++)
		{
			sum_Diff += pow((Crt[i+w-1] - Ref[i+m]), 2);
		}
		if (sum_Diff < minV)
		{
			minV = sum_Diff;
			Idx = w;
		}
	}
	minL = m + 1 - Idx;
}
//功能函数-画面抖动检测
void ViewShake(Mat src, float &k)
{
	if (baseimg.empty())
	{
		baseimg = src.clone();
		k = 0;
		return;
	}
	vector<int> Rsum_src, Csum_src, Rsum_base, Csum_base;
	float meanR_src = 0, meanC_src = 0, meanR_base = 0, meanC_base = 0;

	Row_sum(src, Rsum_src, meanR_src);
	Col_sum(src, Csum_src, meanC_src);
	Row_sum(baseimg, Rsum_base, meanR_base);
	Col_sum(baseimg, Csum_base, meanC_base);

	for (int i = 0; i < Rsum_src.size();i++)
	{
		Rsum_src[i] = Rsum_src[i] - meanR_src;
		Rsum_base[i] = Rsum_base[i] - meanR_base;
	}
	for (int i = 0; i < Csum_src.size(); i++)
	{
		Csum_src[i] = Csum_src[i] - meanC_src;
		Csum_base[i] = Csum_base[i] - meanC_base;
	}

	int R_L = 0, C_L = 0; //行、列向的偏移像素
	Cal_min(Rsum_src, Rsum_base, 20, R_L);  //m初值设置为20
	Cal_min(Csum_src, Csum_base, 20, C_L);

	//自己设计阈值判断是否振动
}

整体来说,有一定的参考价值!

本人希望在分享过程中与各位共同学习、共同提高!

猜你喜欢

转载自blog.csdn.net/bemy1008/article/details/86687793