NL-均值滤波器问题

时间:2018-11-11 16:07:28

标签: c++ opencv imagefilter

我正在尝试使用opencv库实现自己的NL-均值过滤器。但是,在尝试实际使用该滤镜之后,结果图像上出现了黑色像素。

double gaussian(float x, double sigma) 
{
return (1 / (2 * M_PI*sigma*sigma))*(exp(-(x*x) / (2 * sigma*sigma)));
}  

void applyNLMFilter (Mat source, Mat filteredImage, int x, int y, int diameter, double sigmaS,int searchwindow) 
{
int  i1, j1;
int min_sad;
int half = diameter /2 ;
        int min_sad1 = 1000000;
        Mat originblock = source(Rect(y, x, half, half));
        for (i1 = -searchwindow * half + x * half; i1 < searchwindow *  half + x  * half; i1++)
            for (j1 = -searchwindow * searchwindow + y * half; j1 < searchwindow *  half + y * half; j1++)
            {

                if ((i1 < 0) || (j1 < 0) || (i1 > source.cols - half) || (j1 > source.rows - half)) continue;
                else {
                    Mat blcktocmp = source(Rect(i1, j1, half, half));
                    Mat diff;
                    cv::absdiff(originblock, blcktocmp, diff);
                    double s = cv::sum(diff)[0];
                    int sad = cv::sum(diff)[0];
                    if (sad <= min_sad1)
                    {
                        min_sad = sad;
                    }

                }
            }
double iFilteredb = 0, iFilteredg = 0, iFilteredr = 0;
double wP = 0;
int neighbor_x = 0;
int neighbor_y = 0;
for (int i = 0; i < diameter; i++) {
    for (int j = 0; j < diameter; j++) {
        neighbor_x = x - (half - i);
        neighbor_y = y - (half - j);
        Vec3b neighborPixel = source.at<Vec3b>(neighbor_x, neighbor_y), centerPixel = source.at<Vec3b>(x, y);
        double gs = gaussian(min_sad, sigmaS);
        double w = gs;
        iFilteredb = iFilteredb + neighborPixel.val[0] * w;
        iFilteredg = iFilteredg + neighborPixel.val[1] * w;
        iFilteredr = iFilteredr + neighborPixel.val[2] * w;
        wP = wP + w;

    }
}
iFilteredb = iFilteredb / wP;
iFilteredg = iFilteredg / wP;
iFilteredr = iFilteredr / wP;
Vec3b filtered;
filtered.val[0] = iFilteredb;
filtered.val[1] = iFilteredg;
filtered.val[2] = iFilteredr;
filteredImage.at<Vec3b>(x, y) = filtered;
  }  


Mat NLMfilter(Mat source, int diameter, double sigmaS, int searchwindow) 
 {
Mat filteredImage = source.clone();
int width = source.cols;
int height = source.rows;
int half = diameter / 2;
for (int i = half; i < height - diameter; i++) {
    for (int j = half; j < width - diameter; j++) {
        applyNLMFilter(source, filteredImage, i, j, diameter, sigmaS, searchwindow);
    }
}
return filteredImage;

}

结果如下: Original image Filtered image

工作流程-对于每个像素(边界上的像素除外),我正在使用绝对差之和搜索最相似的色块。然后,我使用此总和来计算高斯函数,将其应用于像素值并计算滤波后像素的结果值。 我在哪里弄错了?

0 个答案:

没有答案