OpenCV均值/ SD滤波器

gan*_*oji 11 opencv filter image-segmentation standard-deviation

我把它扔到那里,希望有人会尝试过这种荒谬的事情.我的目标是接收输入图像,并根据每个像素周围的小窗口的标准偏差对其进行分割.基本上,这应该在数学上类似于高斯或盒式滤波器,因为它将应用于围绕每个像素的编译时(或甚至运行时)用户指定的窗口大小,并且目标阵列将包含每个像素处的SD信息,在与原始图像大小相同的图像中.

我们的想法是在HSV空间中的图像上执行此操作,以便我可以轻松找到均匀颜色的区域(即在Hue和Sat平面中具有小局部SD的区域)并从图像中提取它们以进行更深入的处理.

所以问题是,有没有人曾经建立过这样的自定义过滤器?我不知道如何在一个简单的盒式滤波器内核中使用SD,就像用于高斯和模糊的那样,所以我猜我必须使用FilterEngine结构.另外,我忘了提到我在C++中这样做.

非常感谢您的建议和思考.

mev*_*ron 35

维基百科对标准偏差有一个很好的解释,您可以将其用于标准偏差滤波器.

基本上,它归结为使用盒式滤镜模糊图像,使用盒式滤镜模糊图像的方形,并取其差异的平方根.

更新:这可能更好地显示维基百科的等式... 在此输入图像描述

您可以将OpenCV blur函数视为表示感兴趣的邻域的期望值(即,E [X]也称为样本均值).在这种情况下,随机样本X由局部邻域中的图像像素表示.因此,通过使用上述等价,我们sqrt(blur(img^2) - blur(img)^2)在OpenCV中有类似的东西.这样做可以让您计算局部均值和标准差.

另外,万一你好奇数学证明.这种等价性被称为方差计算公式.

以下是在OpenCV中执行此操作的方法:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

Mat mat2gray(const Mat& src)
{
    Mat dst;
    normalize(src, dst, 0.0, 1.0, NORM_MINMAX);
    return dst;
}

int main()
{
    Mat image = imread("coke-can.jpg", 0);

    Mat image32f;
    image.convertTo(image32f, CV_32F);

    Mat mu;
    blur(image32f, mu, Size(3, 3));

    Mat mu2;
    blur(image32f.mul(image32f), mu2, Size(3, 3));

    Mat sigma;
    cv::sqrt(mu2 - mu.mul(mu), sigma);

    imshow("coke", mat2gray(image32f));
    imshow("mu", mat2gray(mu));
    imshow("sigma",mat2gray(sigma));
    waitKey();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下图像:

原版的

在此输入图像描述

意思

在此输入图像描述

标准偏差

在此输入图像描述

希望有所帮助!