采用图像的平均值进行背景减法 - 结果不正确

时间:2013-12-24 20:35:02

标签: visual-c++ opencv image-processing computer-vision background-subtraction

当我尝试总结存储在列表中的N个先前帧然后除以num帧时,生成的背景模型不是预期的。我可以说,因为我早先在同一个视频中尝试过Matlab中的算法。

class TemporalMeanFilter {
private:
    int learningCount;
    list<Mat> history;
    int height, width;

    Mat buildModel(){
        if(history.size() == 0)
            return Mat();

        Mat image_avg(height, width, CV_8U, Scalar(0));
        double alpha = (1.0/history.size());

        list<Mat>::iterator it = history.begin();
        cout << "History size: " << history.size() << " Weight per cell: " << alpha << endl;

        while(it != history.end()){
            image_avg += (*it * alpha);
            it++;
        }

        return image_avg;
    }

public:
    TemporalMeanFilter(int height, int width, int learningCount){
        this->learningCount = learningCount;
        this->height = height;
        this->width = width;
    }

    void applyFrameDifference(Mat& frame_diff, Mat& bg_model, Mat& input_frame){
        if(history.size() == learningCount)
            history.pop_front();

        history.push_back(input_frame);

        bg_model = buildModel();
        frame_diff = bg_model - input_frame;
    }
};

//主要看起来像这样

// ...从文件中读取视频

TemporalMeanFilter meanFilter(height, width, 50); //background subtraction algorithm
meanFilter.applyFrameDifference(diff_frame, bg_model, curr_frame);

// ...在屏幕上显示...编程结束

图像: http://imagegur.com/images/untitled.png

左边是bg_model,中间是curr_frame,右边是输出。

也许是因为CV_U8完成了四舍五入?我尝试更改为CV_32FC1,但程序崩溃了,因为由于某种原因它无法添加两个CV_32FC1矩阵。

非常感谢任何见解。谢谢!

更多信息:

在课堂上,我现在将平均值保留在CV_16UC1 Mat中以防止剪辑,连续添加后如何导致错误。

add function / operator +都将结果类型从CV_16UC1更改为CV8UC1。此错误是由此引起的。有任何建议如何要求它保留原始数据类型? (PS:我礼貌地问了......没有用)

background_model += *it;

OpenCV Error: Bad argument (When the input arrays in add/subtract/multiply/divid
e functions have different types, the output array type must be explicitly speci
fied) in unknown function, file C:\buildslave64\win64_amdocl\2_4_PackSlave-win32
-vc11-shared\opencv\modules\core\src\arithm.cpp, line 1313

1 个答案:

答案 0 :(得分:0)

你说得对,几乎可以肯定是你通过累积缩放的灰度值得到的舍入误差。没有理由为什么它应该使用浮点像素崩溃,所以你应该尝试这样的事情:

Mat buildModel()
{
    if (history.size() == 0)
        return Mat();

    Mat image_avg = Mat::zeros(height, width, CV_32FC1);
    double alpha = (1.0 / history.size());

    list<Mat>::iterator it = history.begin();

    while (it != history.end())
    {
        Mat image_temp;
        (*it).convertTo(image_temp, CV_32FC1);
        image_avg += image_temp;
        it++;
    }
    image_avg *= alpha;

    return image_avg;
}

根据您对结果的处理方式,您可能需要对其进行标准化或重新缩放,或在显示之前转换回灰度等。