Stdfilt в Opencv - PullRequest
       18

Stdfilt в Opencv

4 голосов
/ 07 сентября 2011

В настоящее время я просматриваю документацию по openCV, пытающуюся найти эквивалентный Matlab stdfilt Может ли кто-нибудь указать мне правильное направление?

спасибо.

Ответы [ 3 ]

4 голосов
/ 09 сентября 2011

Глядя на исходный код внутри файла stdfilt.m, мы видим, что он реализован с использованием свертки.

Я перенес код на Python, его нужно переписать на 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')

Результат:

fruits python_stdfilt

Сравнение с версией MATLAB:

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

MATLAB_stdfilt

2 голосов
/ 07 сентября 2011

Я думаю, вам не повезло - есть функция для среднего и стандартного отклонения всего изображения, cvAvgSdv, но ничего для локального стандартного отклонения, насколько я вижу.Тем не менее, это не должно быть слишком сложно, чтобы написать один.

0 голосов
/ 13 октября 2016
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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...