栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

手动实现图像滤波

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手动实现图像滤波

文章目录
  • 图像滤波
    • 实验要求
    • 实现
      • 创建高斯滤波卷积核
        • 示例
      • 零填充
        • 示例
      • 代码
      • 结果

图像滤波 实验要求

实现卷积
基于Python实现函数完成用滤波器h对灰度图像img0进行滤波,返回
滤波后的图像img1,即

i m g 1 = m y I m a g e F i l t e r ( i m g 0 , h ) img1 = myImageFilter(img0, h) img1=myImageFilter(img0,h)

要求滤波后的图像img1与原始输入图像具有相同的尺寸,滤波器h每个维度的大小为奇数(2k + 1, k = 1, 2, · · · )。在进行图像填充的时候可以使用课堂上讲过的任何一种填充方式均可。可以调用Python中NumPy的填充函数,但不能调用任何包括convolve, correlate, fftconvolve等函数(仅可以使用他们来与你自己的实现结果进行对比)。函数的实现需采用矢量化,关于矢量化的例子可参考https://www.pythonlikeyoumeanit.com/Module3_IntroducingNumpy/VectorizedOperations.html.
(提示:尽可能减少for循环的个数)

实现

分析步骤:

  1. 创建高斯滤波卷积核,并做归一化处理
  2. 获取图片的形状(高、宽、通道数)
  3. 图片零填充处理,得到图片副本
  4. 遍历图片副本所有像素点,将卷积核与图片副本的切片进行点乘求和运算,得到输出图片
  5. 输出图片切片,恢复原图形状
创建高斯滤波卷积核

高斯滤波器将中心像素周围的像素按照高斯分布加权平均进行平滑化。
按下面的高斯分布公式计算权值:
g ( x , y , σ ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 g(x,y,sigma) = frac{1}{2pisigma^2}e^{-frac{x^2+y^2}{2sigma^2}} g(x,y,σ)=2πσ21​e−2σ2x2+y2​
并对权值 g g g进行归一化操作。

标准差 σ sigma σ=1.3的8−近邻高斯滤波器如下:
k = 1 16 [ 1 2 1 2 4 2 1 2 1 ] k = frac{1}{16} begin{bmatrix} 1 & 2 &1 \ 2 & 4 & 2 \ 1 & 2 & 1 \ end{bmatrix} k=161​⎣⎡​121​242​121​⎦⎤​

示例
def kernal_maker(k_size, sigma):
    """
    Create a Gaussian kernel
    :param k_size:size of the Gaussian kernal
    :param sigma:standard deviation
    :return:Gaussian kernal
    """
    pad = k_size // 2
    k = np.zeros((k_size, k_size), dtype=np.float)
    for x in range(-pad, -pad + k_size):
        for y in range(-pad, -pad + k_size):
            k[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))

    k /= (2 * np.pi * sigma * sigma)
    k /= k.sum()
    return k
零填充

由于图像的长宽可能不是滤波器大小的整数倍,因此我们需要在图像的边缘补0。

示例
    # Zero padding
    k_size = k.shape[0]
    pad = k_size // 2
    out = np.zeros((h + pad * 2, w + pad * 2, c), dtype=np.float)
    out[pad: pad + h, pad: pad + w] = img0.copy().astype(np.float)
代码
import numpy as np
import cv2 as cv


def myImageFilter(img0, k):
    # YOUR CODE HERE
    """
    Fltering using a given kernel k
    :param img0:image
    :param k: kernal
    :return:filtered image
    """
    if len(img0.shape) == 3:
        h, w, c = img0.shape
    else:
        img0 = np.expand_dims(img0, axis=-1)
        h, w, c = img0.shape

    # Zero padding
    k_size = k.shape[0]
    pad = k_size // 2
    out = np.zeros((h + pad * 2, w + pad * 2, c), dtype=np.float)
    out[pad: pad + h, pad: pad + w] = img0.copy().astype(np.float)

    # filtering
    tmp = out.copy()
    for y in range(h):
        for x in range(w):
            for i in range(c):
                out[pad + y, pad + x, i] = np.sum(k * tmp[y: y + k_size, x: x + k_size, i])

    out = np.clip(out, 0, 255)
    out = out[pad: pad + h, pad: pad + w].astype(np.uint8)
    return out


def kernal_maker(k_size, sigma):
    """
    Create a Gaussian kernel
    :param k_size:size of the Gaussian kernal
    :param sigma:standard deviation
    :return:Gaussian kernal
    """
    pad = k_size // 2
    k = np.zeros((k_size, k_size), dtype=np.float)
    for x in range(-pad, -pad + k_size):
        for y in range(-pad, -pad + k_size):
            k[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))

    k /= (2 * np.pi * sigma * sigma)
    k /= k.sum()
    return k


if __name__ == '__main__':
    # Read image
    # image = cv.imread("../image/example.png")
    image = cv.imread("../image/example_gray.png")
    cv.imshow("input", image)
    # Create Gaussian kernel
    kernal = kernal_maker(k_size=3, sigma=1.3)
    # Gaussian Filter
    image_filtered = myImageFilter(img0=image, k=kernal)
    # Save result
    # cv.imwrite("out.jpg", image_processed)
    cv.imshow("output", image_filtered)
    cv.waitKey(0)
    cv.destroyAllWindows()
结果

input

output

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/321216.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号