就是使用滤波核网格内的像素的平均值作为最终的像素结果.
代码实现:
# @Time : 2022/6/10 11:52
# @Author : Fioman
# @Phone : 13149920693
# @Tips : Talk is Cheap,Show me the code! ^_^^_^
from settings import *
def mean_filter(image, kSize=3):
"""
均值滤波器,使用滤波核内的网格中的像素的均值作为最终结果对图像进行平滑操作
:param image:
:param kSize:
:return:
"""
if len(image.shape) == 3:
H, W, C = image.shape
else:
image = np.expand_dims(image, axis=-1)
H, W, C = image.shape
print("C = {}".format(C))
# Zero Padding
pad = kSize // 2
out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float32)
out[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)
temp = out.copy()
for y in range(H):
for x in range(W):
for c in range(C):
out[pad + y, pad + x, c] = np.mean(temp[y:y + kSize, x:x + kSize, c])
out = out[pad:pad + H, pad:pad + W].astype(np.uint8)
return out
if __name__ == '__main__':
imagePath = os.path.join(OPENCV_100_Q_PATH, "gray_01.bmp")
imageOrginal = cv.imread(imagePath, cv.IMREAD_GRAYSCALE)
meanBlured = mean_filter(imageOrginal, 3)
cv.imshow("Orginal", imageOrginal)
cv.imshow("MeanBlured", meanBlured)
cv.waitKey(0)
Motion Filter
就是取主对角线方向上的像素的平局值,类似这种定义.
# @Time : 2022/6/10 13:52
# @Author : Fioman
# @Phone : 13149920693
# @Tips : Talk is Cheap,Show me the code! ^_^^_^
from settings import *
def motion_filter(image, kSize=3):
if len(image.shape) == 3:
H, W, C = image.shape
else:
image = np.expand_dims(image, axis=-1)
H, W, C = image.shape
# Kernel 对角线矩阵
K = np.diag([1] * kSize).astype(np.float32)
K /= kSize # 求平均值
# zero padding
pad = kSize // 2
out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float32)
out[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)
temp = out.copy()
# filter
for y in range(H):
for x in range(W):
for c in range(C):
out[pad + y, pad + x, c] = np.sum(K * temp[y:y + kSize, x:x + kSize, c])
out = out[pad:pad + H, pad:pad + W].astype(np.uint8)
return out
if __name__ == '__main__':
imagePath = os.path.join(OPENCV_100_Q_PATH,"gray_01.bmp")
imageOriginal = cv.imread(imagePath,cv.IMREAD_GRAYSCALE)
motionFilter = motion_filter(imageOriginal,3)
cv.imshow("Original",imageOriginal)
cv.imshow("MotionFilter",motionFilter)
cv.waitKey(0)
MAX-MIN
滤波器是指使用核大小的网格内像素的最大值和最小值的差值来作为结果对待求的像素位置赋值.
通常用于边缘检测.一般使用在灰度图像上.
代码实现
# @Time : 2022/6/10 14:05
# @Author : Fioman
# @Phone : 13149920693
# @Tips : Talk is Cheap,Show me the code! ^_^^_^
from settings import *
def BGR_to_GRAY(image):
b = image[:, :, 0].copy()
g = image[:, :, 1].copy()
r = image[:, :, 2].copy()
# Gray scale
out = 0.2126 * r + 0.7152 * g + 0.0722 * b
out = out.astype(np.uint8)
return out
def max_min_filter(image, kSize=3):
if len(image.shape) >= 3:
image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
H, W = image.shape
# Zero padding
pad = kSize // 2
out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float32)
out[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)
temp = out.copy()
# filtering
for y in range(H):
for x in range(W):
kernelElement = temp[y:y + kSize, x:x + kSize]
out[pad + y, pad + x] = np.max(kernelElement) - np.min(kernelElement)
out = out[pad:pad + H, pad:pad + W].astype(np.uint8)
return out
if __name__ == '__main__':
imagePath = os.path.join(OPENCV_100_Q_PATH, "gray_01.bmp")
imageOriginal = cv.imread(imagePath, cv.IMREAD_GRAYSCALE)
maxMinFilter = max_min_filter(imageOriginal, 3)
cv.imshow("Original", imageOriginal)
cv.imshow("MaxMinFilter", maxMinFilter)
cv.waitKey(0)
差分滤波器其实就是这个像素,和它前一个像素的差值,作为结果.
分为横向和纵向,一般使用3 * 3的矩阵来表示.
横向差分矩阵,使用计算的中心点像素和它水平的前一个位置的像素的差值作为结果,其他的位置都是0
纵向差分矩阵,使用计算的中心点像素和它垂直的前一个位置的像素的差值作为结果,其他的位置都是0
# @Time : 2022/6/10 14:26
# @Author : Fioman
# @Phone : 13149920693
# @Tips : Talk is Cheap,Show me the code! ^_^^_^
from settings import *
def BGR_to_GRAY(image):
"""
:param image:
:return:
"""
b = image[..., 0].copy()
g = image[..., 1].copy()
r = image[..., 2].copy()
out = 0.2126 * r + 0.7152 * g + 0.0722 * b
out = out.astype(np.uint8)
return out
def difference_filter(image):
if len(image.shape) == 3:
image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
H, W = image.shape
kSize = 3
# Zero Padding
pad = kSize // 2
out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float32)
out[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)
temp = out.copy()
outVer = out.copy()
outHor = out.copy()
kernelVer = np.array([[0, -1, 0], [0, 1, 0], [0, 0, 0]])
kernelHor = np.array([[0, 0, 0], [-1, 1, 0], [0, 0, 0]])
for y in range(H):
for x in range(W):
outVer[pad + y, pad + x] = np.sum(kernelVer * (temp[y:y + kSize, x:x + kSize]))
outHor[pad + y, pad + x] = np.sum(kernelHor * (temp[y:y + kSize, x:x + kSize]))
outver = np.clip(outVer, 0, 255)
outHor = np.clip(outHor, 0, 255)
outver = outver[pad:pad + H, pad:pad + W].astype(np.uint8)
outHor = outHor[pad:pad + H, pad:pad + W].astype(np.uint8)
return outver, outHor
if __name__ == '__main__':
imagePath = os.path.join(OPENCV_100_Q_PATH,"gray_01.bmp")
imageOriginal = cv.imread(imagePath,cv.IMREAD_GRAYSCALE)
difVer,difHor = difference_filter(imageOriginal)
cv.imshow("Original",imageOriginal)
cv.imshow("DifVer",difVer)
cv.imshow("DifHor",difHor)
cv.waitKey(0)
Sobel滤波器可以提取特定方向(纵向或者横向)的边缘,滤波器按照下面的方式定义:
纵向滤波核(y轴方向上的离散导数):
代码实现:
# @Time : 2022/6/10 15:06
# @Author : Fioman
# @Phone : 13149920693
# @Tips : Talk is Cheap,Show me the code! ^_^^_^
from settings import *
def BGR_to_GRAY(image):
b = image[..., 0].copy()
g = image[..., 1].copy()
r = image[..., 2].copy()
out = 0.2126 * r + 0.7152 * g + 0.0722 * b
out = np.clip(out, 0, 255)
return out
def sobel_filter(image):
Ksize = 3
if len(image.shape) == 3:
image = BGR_to_GRAY(image)
H, W = image.shape
# zero padding
pad = Ksize // 2
out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float32)
out[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)
# filter
kernelX = np.array([[1, 0, -1], [2, 0, -2], [1, 0, -1]])
kernelY = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
outX = out.copy()
outY = out.copy()
for y in range(H):
for x in range(W):
outX[y + pad, x + pad] = np.sum(kernelX * out[y:(y + Ksize), x:(x + Ksize)])
outY[y + pad, x + pad] = np.sum(kernelY * out[y:(y + Ksize), x:(x + Ksize)])
outY = np.clip(outY, 0, 255)
outX = np.clip(outX, 0, 255)
outY = outY[pad:pad + H, pad:pad + W].astype(np.uint8)
outX = outX[pad:pad + H, pad:pad + W].astype(np.uint8)
return outX, outY
if __name__ == '__main__':
imagePath = os.path.join(OPENCV_100_Q_PATH,"gray_01.bmp")
imageOriginal = cv.imread(imagePath,cv.IMREAD_GRAYSCALE)
sobelX,sobelY = sobel_filter(imageOriginal)
cv.imshow("Original",imageOriginal)
cv.imshow("SobelX",sobelX)
cv.imshow("SobelY",sobelY)
cv.waitKey(0)