【问题标题】:Frame difference noise?帧差噪声?
【发布时间】:2012-05-24 11:50:59
【问题描述】:

我正在尝试使用帧差异检测运动。如果有动议,我会进入另一个方法,如果没有,我不会进入那个方法。问题是当我使用 absdiff() 或 bitwise_xor() 进行帧差异时,我得到一个嘈杂的帧,它总是被检测为运动。

我试图通过使用 erode() 和 dilate() 方法来消除噪音,它降低了噪音的影响,但仍然有噪音。我怎样才能消除这种噪音?

我当前代码的一部分:

capture >> Frame; // get a new frame from camera

cvtColor(Frame,Frame1,CV_RGB2GRAY);
threshold(Frame1,Frame1,50,255,CV_THRESH_BINARY);

waitKey(500);
capture >> PreFrame;

cvtColor(PreFrame,PreFrame,CV_RGB2GRAY);
threshold(PreFrame,PreFrame,50,255,CV_THRESH_BINARY);

//Result = Frame1 - PreFrame1;
//absdiff(Frame1,PreFrame1,Result);

bitwise_xor(Frame1,PreFrame,Result);
erode(Result,Result,Mat());
dilate(Result,Result,Mat());

imshow("Result",Result);

if (norm(Result,NORM_L1)==0){
    printf(" no change \n")
}
else
{
    // motion detected
}

【问题讨论】:

  • 没有办法完全消除噪音您应该尝试采用与“非常低的变化”一起使用的方法——例如看看噪声的平均值是多少,然后所有低于平均值的帧差异都被视为由于噪声而发生的。都高于平均水平,如果你愿意,可以称之为“高变化”,你会假设图像中存在除噪声之外的影响,然后去计算所需的东西。

标签: c++ image-processing opencv


【解决方案1】:

您可以通过几种不同的方式来减少噪点,只需在捕获帧后立即应用以下技术之一:

模糊(帧内平均)

看看一些不同的模糊运算符,例如:

  1. blur(速度快,但不太流畅)
  2. GaussianBlur(更慢,但更流​​畅)
  3. medianBlur(减少脉冲噪声)

medianBlur 可以很好地控制脉冲噪声,同时保留图像中的边缘。

帧平均(平均不同帧)

  1. accumulate
  2. accumulateWeighted

使用帧平均只需将累积结果除以累积的帧数即可获得平均帧。您可能想要一个 5-10 帧的滚动平均窗口来显着降低噪声。然而,更大的窗口尺寸意味着当物体移入和移出视野时更多的运动模糊。如果您的相机静止不动,这将最有效。

希望有帮助!

【讨论】:

  • 帧平均将消除读出噪声(帧间差异)。模糊会消除 FPN 和 PRNU 等像素差异。
【解决方案2】:

如果获取灰度图像的绝对差异,然后对结果进行阈值处理以消除小的强度变化,会发生什么?这将允许逐帧像素强度的微小变化,同时在有任何显着变化时仍会触发您的运动检测器。

例如:

// Obtain image two images in grayscale
cvtColor(Frame,Frame1,CV_RGB2GRAY);
cvtColor(PreFrame,PreFrame,CV_RGB2GRAY);

// Take the absolute difference, this will be zero for identical
// pixels, and larger for greater differences
absdiff(Frame, PreFrame, Result)

// Threshold to remove small differences
threshold(Result,Result,20,255,CV_THRESH_BINARY);

// Prepare output, using Result as a mask
Mat output = Mat::zeros(Frame.size(), Frame.type());
add(
    Frame,   // Add frame
    0,       // and zero
    output,  // to output
    Result   // Only if result is non-zero
);

您有任何可以分享的示例输入/输出图像吗?

【讨论】:

  • @Mark Ransom 感谢您的帮助,这种方法可以将噪点降到最低,但是框架颜色却以一种奇怪的方式出现,我不知道为什么?!
  • 框架颜色是什么意思?您已转换为灰度,执行图像减法,然后对结果进行阈值处理,因此Result 是对应于图像中任何显着强度变化的二值图像。
  • 之后我必须将帧返回到 RGB 中,所以我使用了 cvtColor(Result,Result1,CV_GRAY2RGB); bitwise_and(Result1,Frame,SResult1);
  • @Amr 我已经用可能的解决方案更新了我的答案。如果我理解正确,您基本上想使用 Result 作为掩码从输入图像中选择特定像素。在示例中,我使用cv::add 作为虚拟函数来完成此操作,尽管可能有更优雅的方法。
  • 是的,这正是我想要的,现在效果很好,非常感谢
【解决方案3】:

通过在获取差异之前对图像进行阈值处理,可以大大增加噪点的效果。直接用absdiff而不是bitwise_xor对灰度图像做减法。

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 2014-10-25
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 2011-09-20
    • 2017-09-26
    • 2011-10-18
    相关资源
    最近更新 更多