最近接触视频诊断,打算参考前辈们的文献资料,实现一个专题。
先从画面抖动检测开始吧。
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);
//自己设计阈值判断是否振动
}
整体来说,有一定的参考价值!
本人希望在分享过程中与各位共同学习、共同提高!
2019.05.23更新
事实证明,该方法鲁棒性有待讨论。