简体   繁体   English

OpenCV:标准化框过滤器平滑

[英]OpenCV : Normalized Box Filter Smoothing

I'm trying to do a simple smoothing filter for my image using 我正在尝试使用以下方法为我的图像做一个简单的平滑过滤器 在此处输入图片说明

and I have my expected result using OpenCV Blur 我有使用OpenCV Blur的预期结果

void blur()
{

   blur(image1, image2, cv::Size(3, 3));


   imshow("Orginal", image1);
   imshow("Filtered", image2);
   waitKey(0);
}

在此处输入图片说明

I have also read up some details from OpenCV: Understanding Kernel 我还从OpenCV中阅读了一些详细信息:了解内核

but I want to learn how to do the filter without using OpenCV features but i'm having some problem understanding convolving an image with some kernel 但我想学习如何在不使用OpenCV功能的情况下进行过滤,但是在理解将图像与某些内核卷积时遇到了一些问题 在此处输入图片说明 在此处输入图片说明

From https://en.wikipedia.org/wiki/Kernel_(image_processing) 来自https://en.wikipedia.org/wiki/内核_(图像处理) 在此处输入图片说明

I tried using my best of knowledge of what I understand so far and Here's my code(" 3x3 matrix ) but theres error at accumulator = image1.at<Vec3b>(x, y) * kernelarray[x + k][y + l]; 我尝试使用到目前为止所了解的知识,这是我的代码(“ 3x3矩阵” ),但是accumulator = image1.at<Vec3b>(x, y) * kernelarray[x + k][y + l];

  Mat image1 = imread("Balloon.jpg", CV_LOAD_IMAGE_ANYCOLOR);
  void filter(Mat image1)
 {
 const int kernelWidth = 3;
 const int kernelHeight = 3;

float kernelarray[kernelWidth][kernelHeight];

int accumulator;

for (int x = 0;x < image1.rows;x++) 

    for (int y = 0; y < image1.cols;y++) {

        accumulator = 0;

        for (int k = 0;k < 3;k++)
        {
            for (int l = 0;l < 3;l++)
            {
                accumulator = image1.at<Vec3b>(x, y) * kernelarray[x + k][y + l];

            }
            image1.at<Vec3b>(x, y) = accumulator;
        }
 }
}

What should I do for me to get the expected result that I wanted? 我应该为我做些什么以获得我想要的预期结果?

Convolution in images is an operation where a pixel color is changed depending on the colors of the neighbors of that pixel. 图像卷积是一种操作,其中像素颜色根据该像素的邻居的颜色而改变。 Each pixel (apart from image edges) has 8 neighbors. 每个像素(图像边缘除外)有8个相邻像素。 If you put the pixel and its neighbors in a matrix, the pixel is centered and neighbors around. 如果将像素及其相邻像素放在矩阵中,则像素居中且周围相邻。

What you do is set a 'weight' (as in weighted average) for each neighbor. 您要做的是为每个邻居设置一个“权重”(以加权平均值计)。 Then you just add the result of multiplying each neighbor by its weight. 然后,您只需添加每个邻居乘以其权重的结果。 The center pixel can also have its own weight. 中心像素也可以有自己的权重。 This is a total 9 multiplications and sums. 这是总共9个乘法和和。 You assign the result (after cropping into 0-maxColor range) to the center pixel. 您将结果(裁剪到0-maxColor范围后)分配给中心像素。

When you want to do this convolution for all pixels in the image, normally you want to use the same weights. 当您要对图像中的所有像素进行卷积时,通常希望使用相同的权重。 This 9 weights group is called "kernel". 这9个权重组称为“内核”。 Different kernels produce different results. 不同的内核产生不同的结果。

If you write the weights in a matrix you get two matrices: pixel and its neighbors, weights for all of them. 如果将权重写在矩阵中,则会得到两个矩阵:pixel及其邻居,所有矩阵的权重。 But this is just a representation. 但这只是一种表示。 No matrix operation is involved here. 这里不涉及矩阵运算

You can use not only 8 neighbors, but perhaps 22... and then you need 23 weights. 您不仅可以使用8个邻居,还可以使用22个邻居,然后需要23个权重。

In your code, kernelarray is not filled with weights. 在您的代码中,kernelarray未填充权重。

Ah, solved it with 啊,解决了

for (int y = 1; y < src.rows - 1; y++) {
    for (int x = 1; x < src.cols - 1; x++) {
        sum = 0.0;
        for (int k = -1; k <= 1;k++) {
            for (int j = -1; j <= 1; j++) {
                sum = sum + Kernel[j + 1][k + 1] * src.at<uchar>(y - j, x - k);

apparently its easier to smooth it with grayscale than with color 显然,用灰度比用颜色平滑更容易

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM