Opencv 高斯滤波

使用高斯滤波器(3×3 大小,标准差 s=1.3)来对imori_noise.jpg进行降噪处理吧!

高斯滤波器是一种可以使图像平滑的滤波器,用于去除噪声。可用于去除噪声的滤波器还有中值滤波器,平滑滤波器、LoG 滤波器。

高斯滤波器将中心像素周围的像素按照高斯分布加权平均进行平滑化。这样的(二维)权值通常被称为卷积核或者滤波器。

但是,由于图像的长宽可能不是滤波器大小的整数倍,因此我们需要在图像的边缘补0。这种方法称作 Zero Padding。并且权值(卷积核)要进行归一化操作(\sum\ g = 1)。

权值 g(x,y,s) = 1/ (s*sqrt(2 * pi)) * exp( - (x^2 + y^2) / (2*s^2))
标准差 s = 1.3 的 8 近邻 高斯滤波器如下:
            1 2 1
K =  1/16 [ 2 4 2 ]
            1 2 1

python实现:

import cv2
import numpy as np

# Read image
img = cv2.imread("imori_noise.jpg")
H, W, C = img.shape


# Gaussian Filter
K_size = 3
sigma = 1.3

## Zero padding
pad = K_size // 2
out = np.zeros((H + pad*2, W + pad*2, C), dtype=np.float)
out[pad:pad+H, pad:pad+W] = img.copy().astype(np.float)

## Kernel
K = np.zeros((K_size, K_size), dtype=np.float)
for x in range(-pad, -pad+K_size):

    for y in range(-pad, -pad+K_size):
        K[y+pad, x+pad] = np.exp( -(x**2 + y**2) / (2* (sigma**2)))
K /= (sigma * np.sqrt(2 * np.pi))
K /= K.sum()

tmp = out.copy()

for y in range(H):
    for x in range(W):
        for c in range(C):
            out[pad+y, pad+x, c] = np.sum(K * tmp[y:y+K_size, x:x+K_size, c])

out = out[pad:pad+H, pad:pad+W].astype(np.uint8)

# Save result
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()

C++实现:

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>

int main(int argc, const char* argv[]){
  cv::Mat img = cv::imread("imori_noise.jpg", cv::IMREAD_COLOR);

  int width = img.rows;
  int height = img.cols;

  cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);

  // prepare kernel
  double s = 1.3;
  int k_size = 3;
  int p = floor(k_size / 2);
  int x = 0, y = 0;
  double k_sum = 0;

  float k[k_size][k_size];
  for (int j = 0; j < k_size; j++){
    for (int i = 0; i < k_size; i++){
      y = j - p;
      x = i - p; 
      k[j][i] = 1 / (s * sqrt(2 * M_PI)) * exp( - (x*x + y*y) / (2*s*s));
      k_sum += k[j][i];
    }
  }

  for (int j = 0; j < k_size; j++){
    for (int i = 0; i < k_size; i++){
      k[j][i] /= k_sum;
    }
  }


  // filtering
  double v = 0;

  for (int j = 0; j < height; j++){
    for (int i = 0; i < width; i++){
      for (int c = 0; c < 3; c++){
    v = 0;
    for (int _j = -p; _j < p+1; _j++){
      for (int _i = -p; _i < p+1; _i++){
        if (((j+_j) >= 0) && ((i+_i) >= 0)){
          v += (double)img.at<cv::Vec3b>(j+_j, i+_i)[c] * k[_j+p][_i+p];
        }
      }
    }
    out.at<cv::Vec3b>(j,i)[c] = v;
      }
    }
  }

  //cv::imwrite("out.jpg", out);
  cv::imshow("answer", out);
  cv::waitKey(0);
  cv::destroyAllWindows();

  return 0;
}

输入:

高斯滤波

输出:

高斯滤波

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程