小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
中值滤波器
中值滤波器好说,opencv自带和函数就能直接用。在OpenCV中,实现中值滤波的函数是cv2.medianBlur(src, ksize)
- src:图片位置
- kszie:卷积核大小
import cv2 as cv
img = cv.imread('d:/Desktop/1.jpg') # 我的桌面上有个1.jpg
res = cv.medianBlur(img, 5)
cv.imshow("original", img)
cv.imshow("result", res)
cv.waitKey(0)
中值滤波会取当前像素点及其周围临近像素点(一共有奇数个像素点)的像素值,将这些像素值排序,然后将位于中间位置的像素值作为当前像素点的像素值。
将其邻域设置为3×3大小,对其3×3邻域内像素点的像素值进行排序(升序降序均可),按升序排序后得到序列值为:
[66,78,90,91,93,94,95,97,101]
。在该序列中,处于中心位置(也叫中心点或中值点)的值是“93”,因此用该值替换原来的像素值78,作为当前点的新像素值,处理结果如下。
最大最小值滤波器
中值滤波器的原理上边讲到了,最大最小值滤波器就是把中值换成最大或者最小值。
opencv没有自带的最大最小值滤波器,所以需要自己写,定义函数的代码如下:
def original(i, j, k, ksize, img):
# 找到矩阵坐标
x1 = y1 = -ksize // 2
x2 = y2 = ksize + x1
temp = np.zeros(ksize * ksize)
count = 0
# 处理图像
for m in range(x1, x2):
for n in range(y1, y2):
if i + m < 0 or i + m > img.shape[0] - 1 or j + n < 0 or j + n > img.shape[1] - 1:
temp[count] = img[i, j, k]
else:
temp[count] = img[i + m, j + n, k]
count += 1
return temp
# 自定义最大值滤波器最小值滤波器
def max_min_functin(ksize, img, flag):
img0 = copy.copy(img)
for i in range(0, img.shape[0]):
for j in range(2, img.shape[1]):
for k in range(img.shape[2]):
temp = original(i, j, k, ksize, img0)
if flag == 0: # 设置flag参数,如果是0就检测最大值,如果是1就检测最小值。
img[i, j, k] = np.max(temp)
elif flag == 1:
img[i, j, k] = np.min(temp)
return img
注意,上边这段代码写的比较简单,只能接受卷积核是方阵的情况。
实际操作一下:
import cv2 as cv
import numpy as np
import copy
def original(i, j, k, ksize, img):
# 找到矩阵坐标
x1 = y1 = -ksize // 2
x2 = y2 = ksize + x1
temp = np.zeros(ksize * ksize)
count = 0
# 处理图像
for m in range(x1, x2):
for n in range(y1, y2):
if i + m < 0 or i + m > img.shape[0] - 1 or j + n < 0 or j + n > img.shape[1] - 1:
temp[count] = img[i, j, k]
else:
temp[count] = img[i + m, j + n, k]
count += 1
return temp
# 自定义最大值滤波器最小值滤波器
def max_min_functin(ksize, img, flag):
img0 = copy.copy(img)
for i in range(0, img.shape[0]):
for j in range(2, img.shape[1]):
for k in range(img.shape[2]):
temp = original(i, j, k, ksize, img0)
if flag == 0:
img[i, j, k] = np.max(temp)
elif flag == 1:
img[i, j, k] = np.min(temp)
return img
img = cv.imread('d:/Desktop/1.png')
min_img = max_min_functin(3, copy.copy(img),1)
max_img = max_min_functin(3, copy.copy(img),0)
cv.imshow("original", img)
cv.imshow("min_img", min_img)
cv.imshow("max_img", max_img)
cv.waitKey(0)
可以看出最大值滤波可以去除图像中的暗斑,同时也会使亮斑增大(膨胀);最小值滤波可以去除图像中的亮斑,同时也会增大暗斑(腐蚀)。