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);
}