OpenCV:标准化盒滤波器平滑

时间:2016-11-20 21:14:10

标签: c++ image opencv image-processing convolution

我尝试使用enter image description here

为我的图片做一个简单的平滑滤镜

我使用OpenCV Blur

获得了我的预期结果
void blur()
{

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


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

enter image description here

我还从中了解了一些细节 OpenCV: Understanding Kernel

但是我想学习如何在不使用OpenCV功能的情况下进行过滤,但我有一些问题需要理解使用某些内核卷积图像 enter image description here enter image description here

来自https://en.wikipedia.org/wiki/Kernel_(image_processing) enter image description here

我尝试使用迄今为止我所理解的最好的知识 这是我的代码(&#34; 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;
        }
 }
}

我应该怎样做才能获得我想要的预期结果?

2 个答案:

答案 0 :(得分:0)

图像中的卷积是根据该像素的邻居的颜色改变像素颜色的操作。每个像素(除了图像边缘)具有8个邻居。如果将像素及其邻居放在矩阵中,则像素居中并且邻居。

您所做的是为每个邻居设置“权重”(如加权平均值)。然后,您只需添加每个邻居乘以其权重的结果。中心像素也可以具有其自身的重量。这是总共9次乘法和求和。您将结果(在裁剪为0-maxColor范围后)分配给中心像素。

如果要对图像中的所有像素进行此卷积,通常需要使用相同的权重。这9个权重组称为“内核”。不同的内核产生不同的结果。

如果在矩阵中写入权重,则会得到两个矩阵:像素及其邻居,所有矩阵的权重。但这仅仅是一种表现形式。 此处不涉及矩阵操作

你不仅可以使用8个邻居,也可以使用22个...然后你需要23个权重。

在你的代码中,kernelarray没有填充权重。

答案 1 :(得分:0)

啊,用

解决了
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);

显然用灰度比使用颜色更容易使其平滑