开发者

Stdfilt in Opencv

I am c开发者_Python百科urrently looking through he documentation of openCV atempting to find the matlab equivelent of stdfilt could anyone point me in the correct direction?

thanks.


Looking at the source code inside the stdfilt.m file, we can see it is implemented using convolution..

I ported the code to Python, it should be straightforward to rewrite in C\C++:

import cv2
import numpy as np

img = cv2.imread('fruits.jpg', True)
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img = img / 255.0

# c = imfilter(I,h,'symmetric');
h = np.ones((3,3))
n = h.sum()
n1 = n - 1
c1 = cv2.filter2D(img**2, -1, h/n1, borderType=cv2.BORDER_REFLECT)
c2 = cv2.filter2D(img, -1, h, borderType=cv2.BORDER_REFLECT)**2 / (n*n1)
J = np.sqrt( np.maximum(c1-c2,0) )

cv2.imshow('stdfilt', J)
cv2.waitKey(0)
cv2.destroyWindow('stdfilt')

The result:

Stdfilt in Opencv

Stdfilt in Opencv

Compare against MATLAB's version:

I = imread('fruits.jpg');
I = im2double(rgb2gray(I));
imshow(stdfilt(I))

Stdfilt in Opencv


I think you're out of luck - there's a function for mean and std dev of an entire image, cvAvgSdv, but nothing for local std dev as far as I can see. Still, it shouldn't be too hard to write one.


template<class T>
cv::Mat     POW2(const cv::Mat& a)
{
    cv::Mat t(a.size(),a.type(),cv::Scalar(0));
    for (int j=0; j<a.rows; j++) {
        const T* ap=a.ptr<T>(j);
        T* tp=t.ptr<T>(j);
        for (int i=0; i<a.cols; i++)    tp[i]=ap[i]*ap[i];
    }
    return t;
}

template<class T>
cv::Mat     SQRT(const cv::Mat& a)
{
    cv::Mat t(a.size(),a.type(),cv::Scalar(0));
    for (int j=0; j<a.rows; j++) {
        const T* ap=a.ptr<T>(j);
        T* tp=t.ptr<T>(j);
        for (int i=0; i<a.cols; i++)    tp[i]=sqrt(ap[i]);
    }
    return t;
}

Mat stdfilt(Mat_<float> const& I, InputArray kernel, int borderType)
{
    Mat G1,G2;
    Mat I2=POW2<float>(I);
    Scalar n=sum(kernel);
    filter2D( I2, G2, CV_32F,kernel, Point(-1,-1),0,borderType);
    G2=G2/(n[0]-1.);
    filter2D( I,  G1, CV_32F,kernel, Point(-1,-1),0,borderType);
    G1=POW2<float>(G1)/(n[0]*(n[0]-1.));
    return SQRT<float>(MAXM<float>(G2-G1,0.));
}


Mat stdfilt(Mat_<float> const& image32f, int ksize, int borderType)
{
    int kernel_size = 1 + 2*ksize;
    Mat kernel = Mat::ones( kernel_size, kernel_size, CV_32F );
    return stdfilt(image32f, kernel, borderType);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜