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:
Compare against MATLAB's version:
I = imread('fruits.jpg');
I = im2double(rgb2gray(I));
imshow(stdfilt(I))
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);
}
精彩评论