【opencv学习】【图像滤波】

原始图像为:
请添加图片描述

一:给图像增加噪声

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


# 展示图像,封装成函数
def cv_show_image(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)  # 等待时间,单位是毫秒,0代表任意键终止
    cv2.destroyAllWindows()

def sp_noise(image,prob):
    '''
    添加椒盐噪声
    prob:噪声比例
    '''
    output = np.zeros(image.shape,np.uint8)
    # thres = 1 - prob
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            rdn = random.random()  # 每次取随机值,判断这个位置的像素点是否应该被替换为噪声?
            if rdn < prob:
                output[i][j] = 255  # 小于某个阈值的设置为255,这个是亮点噪声
            # elif rdn > thres:
            #     output[i][j] = 255  # 大于某个阈值的设置为0,这个就是暗点噪声
            else:
                output[i][j] = image[i][j]
    return output

def gasuss_noise(image, mean=0, var=0.001):
    '''
        添加高斯噪声
        mean : 均值
        var : 方差
    '''
    image = np.array(image/255.0, dtype=float)  # 将图像的数值改到 0 ~ 1
    noise = np.random.normal(mean, var ** 0.5, image.shape)  # 得到一段正态分布的数据,shape值和图像一致
    out = image + noise  # 二者相加就是带图像的噪声了

    # clip 函数解释,对数据做截断操作,a:输入矩阵;a_min:被限定的最小值,所有比a_min小的数都会强制变为a_min;
    # a_max:被限定的最大值,所有比a_max大的数都会强制变为a_max;
    # out:可以指定输出矩阵的对象,shape与a相同
    out = np.clip(out, 0, 1.0)
    out = np.uint8(out*255)  # 图像数值还原到 0 ~ 255
    return out

def normal_noise(img):
    noise = np.zeros(img.shape, np.int8)
    cv2.randn(noise, (0, 0, 0), (100, 100, 100))  # 图像是(H, W, C),通道是三个,要给每个通道都设置均值和方差
    img_noise  = cv2.add(img, noise, dtype=cv2.CV_8UC3)
    return img_noise

def uniform_noise(img):
    noise = np.zeros(img.shape, np.int8)
    cv2.randu(noise, (0, 0, 0), (100, 100, 100))  # 图像是(H, W, C),通道是三个,要给每个通道都设置均值和方差
    img_noise  = cv2.add(img, noise, dtype=cv2.CV_8UC3)
    return img_noise

img = cv2.imread('images/naruto.jpg')  # 读取原始图像
cv_show_image('img_src', img)

# 增加噪声
img_noise = sp_noise(img, 0.1)  # 增加椒盐噪声
cv_show_image('img_noise', img_noise)

# 增加噪声
img_noise = gasuss_noise(img, 0, 0.1)  # 增加正态分布的噪声
cv_show_image('img_noise', img_noise)

# 增加噪声
img_noise = normal_noise(img)  # 增加正态分布的噪声
cv_show_image('img_noise', img_noise)

# 增加噪声
img_noise = uniform_noise(img)  # 增加正态分布的噪声
cv_show_image('img_noise', img_noise)

以椒盐噪声为例
请添加图片描述
二:各种滤波
代码承接上面的函数
1:均值滤波

# 做滤波操作,平滑处理
# 均值滤波: # 在每个像素点的周围卷积核大小的核的范围内,取其这个范围内所有像素点的平均值。
img = cv2.imread('images/naruto.jpg')  # 读取原始图像
img_noise = sp_noise(img, 0.1)  # 增加椒盐噪声
cv_show_image('img_noise', img_noise)
blur = cv2.blur(img_noise, (3, 3))
cv_show_image('blur', blur)

请添加图片描述

2:方框滤波

# 做滤波操作,平滑处理
# 方框滤波: 和均值滤波基本一致,就是可以选择最后有没有可以做归一化的操作,求平均就是归一化的操作
img = cv2.imread('images/naruto.jpg')  # 读取原始图像
img_noise = sp_noise(img, 0.1)  # 增加椒盐噪声
cv_show_image('img_noise', img_noise)
boxblur = cv2.boxFilter(img_noise, -1, (3, 3), normalize=True)  # -1代表使用原图深度,即src.depth()。
cv_show_image('boxblur', boxblur)
boxblur = cv2.boxFilter(img_noise, -1, (3, 3), normalize=False)  # -1代表使用原图深度,即src.depth()。
cv_show_image('boxblur', boxblur)

请添加图片描述
请添加图片描述

3:高斯滤波

# 做滤波操作,平滑处理
# 高斯滤波: # 在每个像素点的周围卷积核大小的核的范围内,按照高斯分布的特点,距离较近的取更大的权重,距离较远的取较小的权重。
# 上述的均值滤波和方框滤波,每一个像素点的权值都是一样的,
# 而高斯分布是人为距离核心像素点越近的,关系越紧密,越更加重视。距离越远的,关系越小,越不应该重视。
img = cv2.imread('images/naruto.jpg')  # 读取原始图像
img_noise = sp_noise(img, 0.1)  # 增加椒盐噪声
cv_show_image('img_noise', img_noise)
gauss_blur = cv2.GaussianBlur(img_noise, (3, 3), 1)  # 1是sigmaX,表示高斯核函数在X方向的的标准偏差
cv_show_image('gauss_blur', gauss_blur)

请添加图片描述

4:中值滤波

# 做滤波操作,平滑处理
# 中值滤波: # 在每个像素点的周围卷积核大小的核的范围内,取其这个范围内所有像素点的中位数值。
# 在均值滤波器中,由于噪声成分被放入平均计算中,所以输出受到了噪声的影响,但在中值滤波器中,由于噪声成分很难选上,所以几乎不会影响到输出。因此同样用3x3区域进行处理,中值滤波消除的噪声能力更胜一筹。中值滤波无论是在消除噪声还是保存边缘方面都是一个不错的方法。
img = cv2.imread('images/naruto.jpg')  # 读取原始图像
img_noise = sp_noise(img, 0.1)  # 增加椒盐噪声
cv_show_image('img_noise', img_noise)
med_blur = cv2.medianBlur(img_noise, 5)  # 5是5x5的核大小的意思
cv_show_image('med_blur', med_blur)

请添加图片描述

5:双边滤波

# 做滤波操作,平滑处理
# 双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点
img = cv2.imread('images/naruto.jpg')  # 读取原始图像
img_noise = sp_noise(img, 0.1)  # 增加椒盐噪声
cv_show_image('img_noise', img_noise)
bi_blur = cv2.bilateralFilter(src=img_noise, d=0, sigmaColor=100, sigmaSpace=15)
cv_show_image('bi_blur', bi_blur)

请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_29367075/article/details/122904990