简体   繁体   中英

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

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

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 在此处输入图片说明 在此处输入图片说明

From https://en.wikipedia.org/wiki/Kernel_(image_processing) 在此处输入图片说明

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];

  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. 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. You assign the result (after cropping into 0-maxColor range) to the center pixel.

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". 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. 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.

In your code, kernelarray is not filled with weights.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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