OpenCV: 加噪滤波算法实现

加噪滤波算法

题目:选择一幅灰度图像,分别添加高斯噪声和椒盐噪声;分别用均值滤波和中值滤波器对两类噪声图像去噪,分析、比较各滤波器对各类噪声的去噪效果。
椒盐噪声???饿了,也叫脉冲噪声


1.库函数

medianBlur是中值滤波,blur是均值滤波。
注意:blur的第二参数,即ksize,要求是tuple,滑动窗口可以取矩形。我自己写的是没有进行padding的,所以最边缘是处理不到的,当然可以自己给边缘全填上0再卷积。用库还是舒服啊!

x1 = cv2.medianBlur(dstImg_salt, 3)
x2 = cv2.blur(dstImg_salt, (3, 3))
cv2.imshow("a", dstImg_aver)
cv2.imshow("b", x2)

2.噪声滤波算法

这里读取图片的时候要注意,我也是刚翻源码发现的,就是opencv默认读进来图片是BGR的,如果指定了因此使用cvtColor的时候要小心。当然也可以在读取图片时设置。
然后代码里的高斯噪声,我看别人好像用了公式计算二元高斯分布,我比较懒,先用库里的凑合一下。

import cv2
import random
import numpy as np


def SaltNoise(srcImg, n):
    dstImg = srcImg.copy()
    shape = dstImg.shape
    for i in range(n):
        x = random.randint(0, 1000) % shape[0]
        # 更优雅的话范围直接设在行数内取随机数
        y = random.randint(0, 1000) % shape[1]
        if random.randint(0, 2):
            dstImg[x][y] = 255
        else:
            dstImg[x][y] = 0
    return dstImg


def GuassianNoise(srcImg, means, sigma):
    dstImg = srcImg.copy()
    shape = dstImg.shape
    for i in range(shape[0]):
        for j in range(shape[1]):
            dstImg[i][j] += random.gauss(means, sigma) * 32
            # 乘32是要扩大,你想想个位数变动能看出来变化么。
            if dstImg[i][j] > 255:
                dstImg[i][j] = 255
            elif dstImg[i][j] < 0:
                dstImg[i][j] = 0
    return dstImg


img = cv2.imread("sample.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

dstImg_salt = SaltNoise(img_gray, 3000)
dstImg_guass = GuassianNoise(img_gray, 2, 0.8)


def average_filter(srcImg, width):
# width设定正方形窗口宽度,为奇数
    dstImg = srcImg.copy()
    shape = dstImg.shape
    d = int((width-1)/2)
    for i in range(d, shape[0]-d):
        for j in range(d, shape[1]-d):
            box = srcImg[i-d:i+d+1, j-d:j+d+1]
            box_mean = box.mean()
            dstImg[i][j] = round(box_mean)
    return dstImg


def median_filter(srcImg, width):
    dstImg = srcImg.copy()
    shape = dstImg.shape
    d = int((width - 1) / 2)
    for i in range(d, shape[0] - d):
        for j in range(d, shape[1] - d):
            box = srcImg[i-d:i+d+1, j-d:j+d+1]
            box_sorted = np.sort(box.flat)
            dstImg[i][j] = box_sorted[int((width ** 2 + 1)/2)]
    return dstImg


dstImg_aver = average_filter(dstImg_salt, 3)
dstImg_medi = median_filter(dstImg_salt, 3)
row1 = np.hstack([img_gray, dstImg_salt])
row2 = np.hstack([dstImg_aver, dstImg_medi])
IMG_MIX = np.vstack([row1, row2])
# 拼接图片
cv2.imshow("Salt & average & median", IMG_MIX)

dstImg_aver = average_filter(dstImg_guass, 3)
dstImg_medi = median_filter(dstImg_guass, 3)
row1 = np.hstack([img_gray, dstImg_guass])
row2 = np.hstack([dstImg_aver, dstImg_medi])
IMG_MIX2 = np.vstack([row1, row2])
cv2.imshow("Guass & average & median", IMG_MIX2)

cv2.imwrite("Salt & average & median.jpg", IMG_MIX)
cv2.imwrite("Guass & average & median.jpg", IMG_MIX2)

cv2.waitKey()

你可能感兴趣的:(机器视觉)