PS:中值滤波的概念和原理很多人都能用嘴说出来,但是有时候面试时就是需要手写中值滤波的操作,关键在面试时也没有那么多时间让你去考虑,所以在此记录一下。
中值滤波概念就不具体展开了, 简单点就是利用一个 k*k 的滑窗,通过用这个小区域的中位数来代替产生滑窗的中心像素的像素值,
有关滤波、去噪的知识可以见:https://www.cnblogs.com/E-Dreamer-Blogs/p/10458846.html。
python实现
def Median_filtering(image,window_size): #image为传入灰度图像,window_size为滤波窗口大小
high, wide = image.shape
img = image.copy()
mid = (window_size-1) // 2
med_arry = []
for i in range(high-window_size):
for j in range(wide-window_size):
for m1 in range(window_size):
for m2 in range(window_size):
med_arry.append(int(image[i+m1,j+m2]))
med_arry.sort() #对窗口像素点排序
img[i+mid,j+mid] = med_arry[(len(med_arry)+1) // 2] #将滤波窗口的中值赋给滤波窗口中间的像素点
del med_arry[:]
print("completed!")
return img
if __name__ == "__main__":
img_path = "F:/python_code/test_make_other/2020-6-3-编写中值滤波"
img_name = "./0.jpg"
img = cv2.imread(img_name)
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
new_img = Median_filtering(img,3)
cv2.imwrite("Median_filtering.jpg",new_img)
C++ 实现
void medianFilter(unsigned char* Input_img, unsigned char* out_img, int width, int height)
{
memcpy(out_img, Input_img, width * height * sizeof(unsigned char));
for (int j = 1; j < height - 1; j++)
{
for (int i = 1; i < width - 1; i++)
{
int k = 0;
unsigned char window[9]; // 3 * 3 的滑窗
for (int jj = j - 1; jj < j + 2; ++jj)
for (int ii = i - 1; ii < i + 2; ++ii)
window[k++] = Input_img[jj * width + ii]; // 将元素9个9个的放入到window中
// Order elements (only half of them) 排序
for (int m = 0; m < 5; ++m) // 选择排序
{
int min = m;
for (int n = m + 1; n < 9; ++n)
if (window[n] < window[min])
min = n;
// Put found minimum element in its place
swap(window[m], window[min]);
}
out_img[j * width + i] = window[4];// window[4] 即为中位数
}
}
}