c ++ Opencv accumulateWeighted - 奇怪的行为

时间:2013-09-11 18:36:51

标签: c++ opencv image-processing visual-studio-2012 background-subtraction

我正试图从我的摄像头获得帧的运行平均值,但在几秒之后,平均帧的图像变得更亮更亮,而不是白色。

我的相机以3级通道提供灰度图像。 我在Windows 7,Visualstudio 2012,opencv 243

#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc, char* argv[])
{
    VideoCapture cap(0);
    Mat frame1;
    cap.read(frame1);
    Mat acc = Mat::zeros(frame1.size(), CV_32FC1);

    while(1){
        Mat frame;
        Mat gray;
        cap.read(frame);
        cvtColor(frame ,gray ,CV_BGR2GRAY,0);
        accumulateWeighted(gray, acc,0.005);
        imshow("gray", gray);
        imshow("acc", acc);
        waitKey(1); //don't know why I need it but without it the windows freezes
    }
}
谁能告诉我我做错了什么? 谢谢!

2 个答案:

答案 0 :(得分:2)

这里的问题是imshow如何将矩阵值映射到像素值。通常,来自凸轮的原始数据以整数数据类型形式出现,通常在[0,255]范围内。 accumulateWeighted函数执行您期望的操作并计算帧的运行平均值。因此acc是一个浮点矩阵,其值在[0,255]中。

现在,当您将该矩阵传递给imshow时,矩阵值需要映射到强度。由于数据类型是浮点类型,因此0将映射为黑色,1将映射为白色,并且该范围之外的所有内容都将被剪切。因此,只有当图像的某个区域非常黑暗且保持这种状态时,运行平均值才会保持在1以下,并且会映射到纯白色以外的颜色。

幸运的是,修复很简单:

imshow(“acc”,acc / 255);

答案 1 :(得分:1)

我为这个问题找到了更优雅的解决方案。您需要的功能已由OpenCV提供。这适用于3通道彩色或1通道灰度图像:

方法convertScaleAbs

内联文档

  

缩放数组元素,计算绝对值并将结果转换为8位无符号整数:dst(i)= saturate_castabs(src(i)* alpha + beta)

<强>特征

convertScaleAbs(InputArray src, OutputArray dst, double alpha=1, double beta=0)

示例代码

// Variables
Mat frame;
Mat accumulator;
Mat scaled;

// Initialize the accumulator matrix
accumulator = Mat::zeros(frame.size(), CV_32FC3);

while(1){
   // Capture frame
   capture >> frame;

   // Get 50% of the new frame and add it to 50% of the accumulator
   accumulateWeighted(frame, accumulator, 0.5);

   // Scale it to 8-bit unsigned
   convertScaleAbs(accumulator, scaled);

   imshow("Original", frame);

   imshow("Weighted Average", scaled);

   waitKey(1);
}