关于python:中值滤波理解

45次阅读

共计 2815 个字符,预计需要花费 8 分钟才能阅读完成。

import numpy as np
import cv2
from copy import deepcopy
from PIL import Image
from matplotlib import pyplot as plt

"""制作噪声图像"""
def add_salt_noise(img, snr=0.5):
    SNR = snr  # 指定信噪比 (默认 0.5)
    size = img.size  # 获取总共像素个数
    # print(type(size))
    noiseSize = int(size * (1 - SNR))
    for i in range(0, noiseSize):
        # 随机获取 某个点
        xi = int(np.random.uniform(0, img.shape[1]))
        xj = int(np.random.uniform(0, img.shape[0]))
        if img.ndim == 2:  # 判断是否为 2 维图像 (即灰度图像)
            img[xj, xi] = 0  # 设置值为黑点
        elif img.ndim == 3:
            img[xj, xi] = 0  # 设置值为黑点,也能够设置为红色 255
    return img

"""黑白图中值滤波"""
def median_Blur(img, filiter_size=3):  # 当输出的图像为彩色图像
    image_copy = np.array(img, copy=True).astype(np.float32)
    processed = np.zeros_like(image_copy)
    middle = int(filiter_size / 2)
    r = np.zeros(filiter_size * filiter_size)
    g = np.zeros(filiter_size * filiter_size)
    b = np.zeros(filiter_size * filiter_size)

    for i in range(middle, image_copy.shape[0] - middle):
        for j in range(middle, image_copy.shape[1] - middle):
            count = 0
            # 顺次取出模板中对应的像素值
            for m in range(i - middle, i + middle + 1):
                for n in range(j - middle, j + middle + 1):
                    r[count] = image_copy[m][n][0]
                    g[count] = image_copy[m][n][1]
                    b[count] = image_copy[m][n][2]
                    count += 1
            r.sort()
            g.sort()
            b.sort()
            processed[i][j][0] = r[int(filiter_size * filiter_size / 2)]
            processed[i][j][1] = g[int(filiter_size * filiter_size / 2)]
            processed[i][j][2] = b[int(filiter_size * filiter_size / 2)]
    processed = np.clip(processed, 0, 255).astype(np.uint8)
    return processed


"""灰度图中值滤波"""
def median_Blur_gray(img, filiter_size=3):  # 当输出的图像为灰度图像
    image_copy = np.array(img, copy=True).astype(np.float32)
    processed = np.zeros_like(image_copy)
    middle = int(filiter_size / 2)

    for i in range(middle, image_copy.shape[0] - middle):
        for j in range(middle, image_copy.shape[1] - middle):
            temp = []
            for m in range(i - middle, i + middle + 1):
                for n in range(j - middle, j + middle + 1):
                    if m - middle < 0 or m + middle + 1 > image_copy.shape[0] or n - middle < 0 or n + middle + 1 > \
                            image_copy.shape[1]:
                        temp.append(0)
                    else:
                        temp.append(image_copy[m][n])
                    # count += 1
            temp.sort()
            processed[i][j] = temp[(int(filiter_size * filiter_size / 2) + 1)]
    processed = np.clip(processed, 0, 255).astype(np.uint8)
    return processed


if __name__ == "__main__":
    img = input("Please input name of image:")  # 默认是 string 类型
    img = cv2.imread(img)
    print("img.shape:", img.shape)

    # plt.imshow 显示 cv2.imread 读取的图像蓝与红有区别
    b, g, r = cv2.split(img)
    src_img = cv2.merge([r, g, b])

    img_demo = deepcopy(src_img)    #使得两图像不烦扰
    snr = float(input("Please input signal noise ratio:"))
    img_salt = add_salt_noise(img_demo, snr)

    filiter_size = int(input("Please input size of filiter:"))
    median_blur = median_Blur(img_salt, filiter_size)

    plt.figure("Image processing---MedianBlur")  # 图像窗口名称
    plt.subplot(1, 3, 1)
    plt.imshow(src_img)
    plt.axis('off')  # 关掉坐标轴
    plt.title("src_img")

    plt.subplot(1, 3, 2)
    plt.imshow(img_salt)
    plt.axis('off')  # 关掉坐标轴
    plt.title("img_salt")

    plt.subplot(1, 3, 3)
    plt.imshow(median_blur)
    plt.axis('off')  # 关掉坐标轴
    plt.title("median_blur")

    plt.tight_layout()  # 调整整体空白
    plt.subplots_adjust(left=None, bottom=None, right=None, top=None,
                        wspace=None, hspace=None)  # 调整子图间距
    plt.savefig("reult.png", dpi=1000)
    plt.show()

信噪比为 0.5,卷积核为 3,进行中值滤波失去了这样的比照图:

信噪比为 0.9,卷积核为 3,进行中值滤波失去了这样的比照图:

正文完
 0