Opencv_100问_第三章 (11-15)

文章目录

      • 11. 均值滤波器
      • 12. Motion Filter(运动滤波)
      • 13. MAX-MIN滤波器
      • 14. 差分滤波器 (Differential Filter)
      • 15. Sobel滤波器

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

Opencv_100问_第三章 (11-15)_第1张图片

纵向差分矩阵,使用计算的中心点像素和它垂直的前一个位置的像素的差值作为结果,其他的位置都是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轴方向上的离散导数):

Opencv_100问_第三章 (11-15)_第2张图片

代码实现:

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

你可能感兴趣的:(opencv,计算机视觉,python)