中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值.
中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。
使用中值滤波器(3x 3大小)来对imori_noise.jpg
进行降噪处理吧!
中值滤波器是一种可以使图像平滑的滤波器。这种滤波器用滤波器范围内(在这里是3×3)像素点的中值进行滤波,在这里也采用 Zero Padding。
python实现:
import cv2
import numpy as np
# Read image
img = cv2.imread("imori_noise.jpg")
H, W, C = img.shape
# Median Filter
K_size = 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)
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.median(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);
int k_size = 3;
int p = floor(k_size / 2);
// filtering
double v = 0;
int vs[k_size * k_size];
int count = 0;
for (int j = 0; j < height; j++){
for (int i = 0; i < width; i++){
for (int c = 0; c < 3; c++){
v = 0;
count = 0;
for (int i = 0; i < k_size * k_size; i++){
vs[i] = 999;
}
for (int _j = -p; _j < p+1; _j++){
for (int _i = -p; _i < p+1; _i++){
if (((j+_j) >= 0) && ((i+_i) >= 0)){
vs[count++] = (int)img.at<cv::Vec3b>(j+_j, i+_i)[c];
}
}
}
std::sort(vs, vs+(k_size * k_size));
out.at<cv::Vec3b>(j,i)[c] = (uchar)vs[int(floor(count / 2)) + 1];
}
}
}
//cv::imwrite("out.jpg", out);
cv::imshow("answer", out);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
输入:
输出: