图像处理入门100题(二)

图像处理入门100题(二)

本篇记录了自己写的GIthub上的ImageProcessing 100 Wen的问题11-20的答案,注释里包含了一些自己的感悟。为了方便,注释是用英文写的。

这10个题目主要是各种滤波方法,本质上还是卷积运算,不同的滤波方法有不同的卷积核。

值得注意的是Zero Padding方法,以保持卷积运算后图像的大小不变。

LoG滤波中,卷积核要归一化。

问题序号题目
11均值滤波
12运动滤波(Motion Filter)
13MAX-MIN 滤波
14差分滤波
15Sobel 滤波
16Prewitt 滤波
17Laplacian 滤波
18Emboss 滤波
19LoG滤波
20绘制直方图

Python答案如下,结尾包含了问题的验证。注意,引用了answer1(题目1-10的答案),主要用的是图像灰度化处理。

import cv2.cv2
import numpy as np
import matplotlib.pyplot as plt
import answer1


# Question 11
# Mean Filter
# use the mean of kernel to filter
# Answer

def mean_filter(img, k=3):
    if len(img.shape) == 3:
        H, W, C = img.shape
    else:
        np.expand_dims(img, axis=-1)
        H, W, C = img.shape

    # Zero Padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad, C), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = img.astype(np.float)

    # Mean filter
    out_old = 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(out_old[y:y + k, x:x + k, c])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out


# Question 12
# motion filter
# use the mean of values on the diagonal of kernel to filer
# Answer

def motion_filter(img, k=3):
    if len(img.shape) == 3:
        H, W, C = img.shape
    else:
        np.expand_dims(img, axis=-1)
        H, W, C = img.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad, C), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = img.astype(np.float)

    # Build the kernel
    kernel = np.identity(k, dtype=np.float) / k

    # Motion filter
    out_old = out.copy()

    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.sum(kernel * out_old[y:y + k, x:x + k, c])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out


# Question 13
# max-min filter
# use the value of (max-min) in kernel to filter, available to gray
# Answer

def max_min_filter(img, k=3):
    gray = answer1.RGB2GRAY(img)

    if gray.shape == 3:
        H, W, C = gray.shape
    else:
        gray = np.expand_dims(gray, axis=-1)
        H, W, C = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad, C), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # max-min filter
    out_old = out.copy()

    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.max(out_old[y:y + k, x:x + k, c]) - np.min(out_old[y:y + k, x:x + k, c])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out


# Question 14
# differential filter
# get the difference between two conjecture pixels
# Answer

def differential_filter(img):
    k = 3
    gray = answer1.RGB2GRAY(img)
    H, W = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # Build vertical kernel
    kernel_v = [[0., -1., 0.], [0., 1., 0.], [0., 0., 0.]]

    # Build horizon kernel
    kernel_h = [[0., 0., 0.], [-1., 1., 0.], [0., 0., 0.]]

    # filter
    out_v = out.copy()
    out_h = out.copy()

    for y in range(H):
        for x in range(W):
            out_v[pad + y, pad + x] = np.sum(kernel_v * out[y:y + k, x:x + k])
            out_h[pad + y, pad + x] = np.sum(kernel_h * out[y:y + k, x:x + k])

    out_v = np.clip(out_v, 0, 255)
    out_v = out_v[pad:pad + H, pad:pad + W].astype(np.uint8)

    out_h = np.clip(out_h, 0, 255)
    out_h = out_h[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out_v, out_h


# Question 15
# soble filter
# Answer

def sobel_filter(img):
    k = 3
    gray = answer1.RGB2GRAY(img)
    H, W = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # Build vertical kernel
    kernel_v = [[1., 2., 1.], [0., 0., 0.], [-1., -2., -1.]]

    # Build horizon kernel
    kernel_h = [[1., 0., -1.], [2., 0., -2.], [1., 0., -1.]]

    # filter
    out_v = out.copy()
    out_h = out.copy()

    for y in range(H):
        for x in range(W):
            out_v[pad + y, pad + x] = np.sum(kernel_v * out[y:y + k, x:x + k])
            out_h[pad + y, pad + x] = np.sum(kernel_h * out[y:y + k, x:x + k])

    out_v = np.clip(out_v, 0, 255)
    out_v = out_v[pad:pad + H, pad:pad + W].astype(np.uint8)

    out_h = np.clip(out_h, 0, 255)
    out_h = out_h[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out_v, out_h


# Question 16
# Prewitt filter
# Answer

def prewitt_filter(img):
    k = 3
    gray = answer1.RGB2GRAY(img)
    H, W = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # Build vertical kernel
    kernel_v = [[-1., -1., -1.], [0., 0., 0.], [1., 1., 1.]]

    # Build horizon kernel
    kernel_h = [[-1., 0., 1.], [-1., 0., 1.], [-1., 0., 1.]]

    # filter
    out_v = out.copy()
    out_h = out.copy()

    for y in range(H):
        for x in range(W):
            out_v[pad + y, pad + x] = np.sum(kernel_v * out[y:y + k, x:x + k])
            out_h[pad + y, pad + x] = np.sum(kernel_h * out[y:y + k, x:x + k])

    out_v = np.clip(out_v, 0, 255)
    out_v = out_v[pad:pad + H, pad:pad + W].astype(np.uint8)

    out_h = np.clip(out_h, 0, 255)
    out_h = out_h[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out_v, out_h


# Question 17
# Laplacian filter
# Answer

def laplacian_filter(img):
    k = 3
    gray = answer1.RGB2GRAY(img)
    H, W = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # Build vertical kernel
    kernel = [[0., 1., 0.], [1., -4., 1.], [0., 1., 0.]]

    # filter
    out_old = out.copy()

    for y in range(H):
        for x in range(W):
            out[pad + y, pad + x] = np.sum(kernel * out_old[y:y + k, x:x + k])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out


# Question 18
# Emboss filter
# Answer

def emboss_filter(img):
    k = 3
    gray = answer1.RGB2GRAY(img)
    H, W = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # Build vertical kernel
    kernel = [[-2., -1., 0.], [-1., 1., 1.], [0., 1., 2.]]

    # filter
    out_old = out.copy()

    for y in range(H):
        for x in range(W):
            out[pad + y, pad + x] = np.sum(kernel * out_old[y:y + k, x:x + k])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out


# Question 19
# LoG filter
# Gaussian filter + Laplacian filter
# Answer

def log_filter(img, k=5, sigma=3):
    gray = answer1.RGB2GRAY(img)

    if len(gray.shape) == 3:
        H, W, C = gray.shape
    else:
        gray = np.expand_dims(gray, axis=-1)
        H, W, C = gray.shape

    # Zero padding
    pad = int((k - 1) / 2)
    out = np.zeros((H + 2 * pad, W + 2 * pad, C), dtype=np.float)
    out[pad:pad + H, pad:pad + W] = gray.astype(np.float)

    # build filter
    kernel = np.zeros((k, k), dtype=np.float)
    for y in range(-pad, k - pad):
        for x in range(-pad, k - pad):
            kernel[pad + y, pad + x] = (np.square(x) + np.square(y) - np.square(sigma)) * (
                np.exp((-(np.square(x) + np.square(y))) / (2 * np.square(sigma))))

    kernel = kernel / (2 * np.pi * np.power(sigma, 6))
    kernel = kernel / np.sum(kernel)

    # filter
    out_old = out.copy()

    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.sum(kernel * out_old[y:y + k, x:x + k, c])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)

    return out

# Question 20
# hist plot
# to present the times of piexl value
# Answer

def hist_plot(img):
    plt.hist(img.ravel(), bins=255, rwidth=0.8, range=(0, 255))
    plt.show()


# Test

# Answer 11
# img = cv2.imread("imori.jpg")
#
# img11 = mean_filter(img)
#
# cv2.imshow("Mean Filter", img11)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 12
# img = cv2.imread("imori.jpg")
#
# img12 = motion_filter(img)
#
# cv2.imshow("Mean Filter", img12)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Annswer 13
# img = cv2.imread("imori.jpg")
#
# img13 = max_min_filter(img)
#
# cv2.imshow("Max-Min Filter", img13)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 14
# img = cv2.imread("imori.jpg")
#
# img14_v, img14_h = differential_filter(img)
# cv2.imshow("Mean Filter Vertical", img14_v)
# cv2.imshow("Mean Filter Horizon", img14_h)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 15
# img = cv2.imread("imori.jpg")
#
# img15_v, img15_h = sobel_filter(img)
# cv2.imshow("Sobel Filter Vertical", img15_v)
# cv2.imshow("Sobel Filter Horizon", img15_h)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 16
# img = cv2.imread("imori.jpg")
#
# img16_v, img16_h = prewitt_filter(img)
# cv2.imshow("Prewitt Filter Vertical", img16_v)
# cv2.imshow("Prewitt Filter Horizon", img16_h)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 17
# img = cv2.imread("imori.jpg")
#
# img17 = laplacian_filter(img)
# cv2.imshow("Laplacian Filter Vertical", img17)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 18
# img = cv2.imread("imori.jpg")
#
# img18 = emboss_filter(img)
# cv2.imshow("Laplacian Filter Vertical", img18)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 19
# img = cv2.imread("imori_noise.jpg")
#
# img19 = log_filter(img)
# cv2.imshow("LoG Filter Vertical", img19)
#
# cv2.waitKey(0)
# cv2.destroyAllWindows()

# Answer 20
# img = cv2.imread("imori_dark.jpg")
#
# hist_plot(img)

用到的图片
imori.jpg
imori.jpg
imori_nosie.jpg
imori_nosie.jpg
imori_dark.jpg
imori_dark.jpg

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值