Opencv_100问_第三章 (11-15)

11. 均值滤波器

就是使用滤波核网格内的像素的平均值作为最终的像素结果.
代码实现:

# @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)

12. Motion Filter(运动滤波)

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)

13. MAX-MIN滤波器

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)

14. 差分滤波器 (Differential Filter)

差分滤波器其实就是这个像素,和它前一个像素的差值,作为结果.
分为横向和纵向,一般使用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)

15. Sobel滤波器

Sobel滤波器可以提取特定方向(纵向或者横向)的边缘,滤波器按照下面的方式定义:
纵向滤波核(y轴方向上的离散导数):


横向滤波核(x轴方向上的离散导数):

代码实现:

# @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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值