原理:中值滤波的实质就是对滤波窗口大小内的像素点进行排序,然后选择该像素范围内的中值为输出的像素值。中值滤波的主要功能是去除椒盐噪声,类似于黑白电视机的雪花点。
C++:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
Mat medianBLUR(const Mat&img, Size winksize, int borderType = BORDER_DEFAULT)
{
//窗口尺寸
int H = winksize.height;
int W = winksize.width;
//窗口半径
int h = (H - 1) / 2;
int w = (W - 1) / 2;
//图像边界扩充
Mat expand_image;
copyMakeBorder(img, expand_image, h, h, w, w, borderType);
//图像尺寸
int rows = img.rows;
int cols = img.cols;
Mat mediansrc;
mediansrc.create(rows,cols,CV_8UC1);
Mat region, re_region, result_region;
for (int i = 0; i< rows; i++)
{
for (int j = 0; j < cols; j++)
{
region = expand_image(Rect(j, i, W, H)).clone();
//将滤波窗口转换为1×1矩阵
re_region = region.reshape(1, 1);
//像素排序
cv::sort(re_region, result_region, SORT_EVERY_ROW);
uchar number = result_region.at<uchar>(0, ((H*W - 1) / 2));
mediansrc.at<uchar>(i ,j) = number;
}
}
return mediansrc;
};
int main()
{
Mat src,dst;
src=imread("D:/testimage/dog1.jpg");
cvtColor(src, src, COLOR_BGR2GRAY);
dst = medianBLUR(src, Size(7, 7), BORDER_DEFAULT);
imshow("original image", src);
imshow("median image", dst);
waitKey(0);
return 0;
};
Python:
import cv2 as cv
import numpy as np
import random
#椒盐噪声图像
def addsalt(dst,number):
rows,cols=dst.shape[:2]
saltdst=np.copy(dst)
for i in range(number):
m = random.randint(0,rows-1)
n = random.randint(0, cols - 1)
saltdst[m][n]=255
return saltdst
def median_blur(img,ksize):
rows,cols=img.shape
#窗口半径
h = (ksize[0] - 1) // 2
w = (ksize[1] - 1) // 2
#创建中值滤波空白图像
medianblur_image=np.zeros(img.shape,img.dtype)
#扩充图像边界
expand_image=cv.copyMakeBorder(img,h,h,w,w,borderType=cv.BORDER_DEFAULT)
for i in range(rows):
for j in range(cols):
region=expand_image[i:i+h,j:j+w]
medianblur_image[i][j]=np.median(region)
j+=1
i+=1
return medianblur_image
if __name__=="__main__":
img=cv.imread("D:/testimage/dog0.jpg")
dst=addsalt(img,1000)
gray_dst=cv.cvtColor(dst,cv.COLOR_BGR2GRAY)
cv.imshow("original image",gray_dst)
#7×7的中值滤波窗口
src=median_blur(gray_dst,(7,7))
cv.imshow("medianblur_src",src)
cv.waitKey(0)
cv.destroyAllWindows()
结果: