数字图像处理实验—数字图像增强

 完整代码在 FchZero/Digita_Image_Processing_Experiment (github.com)

一、实验目的

1.熟悉并学会opencv-python中图像增强的相关函数;

2.了解图像增强的方法、去噪的方法和效果。

二、实验原理

图像增强是指按特定的需要突出一幅图像中的某些信息,同时,消弱或去除某些不需要的信息的处理方法。其主要目的是处理后的图像对某些特定的应用比原来的图像更加有效。

图像增强技术主要有直方图修改处理、图像平滑化处理、图像尖锐化处理和彩色处理技术等。

1.直方图

直方图是多种空间域处理技术的基础。直方图操作能有效地用于图像增强。除了提供有用的图像统计资料外,直方图固有的信息在其他图像处理应用中也是非常有用的,如图像压缩与分割。直方图在软件中易于计算,也适用于商用硬件设备,因此,它们成为了实时图像处理的一个流行工具。直方图是图像的最基本的统计特征,它反映的是图像的灰度值的分布情况。直方图均衡化的目的是使图像在整个灰度值动态变化范围内的分布均匀化,改善图像的亮度分布状态,增强图像的视觉效果。灰度直方图是图像预处理中涉及最广泛的基本概念之一。图像的直方图事实上就是图像的亮度分布的概率密度函数,是一幅图像的所有象素集合的最基本的统计规律。直方图反映了图像的明暗分布规律,可以通过图像变换进行直方图调整,获得较好的视觉效果。直方图均衡化是通过灰度变换将一幅图像转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数的过程。

2.图像锐化

图像锐化(image sharpening)是补偿图像的轮廓,增强图像的边缘及灰度跳变的部 分,使图像变得清晰,分为空域处理和频域处理两类。

2.1.空域

 ( 1) Roberts 算子
Roberts 算法又称为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算
检测边缘线条。常用来处理具有陡峭的低噪声图像,当图像边缘接近于正 45 度或负 45
时,该算法处理效果更理想。
Roberts 算子的模板分为水平方向和垂直方向,如下所示:

2) Prewitt 算子
Prewitt 算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,
在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空
间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一
个检测垂直边缘。 Prewitt 算法适合用来识别噪声较多、灰度渐变的图像;水平和竖直方向
上的卷积模板如下所示:

3) Sobel 算子
Sobel 算法 ( 索贝尔算子 ) 是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微
分求导。该算子用于计算图像明暗程度近似值,根据图像边缘旁边明暗程度把该区域内超过
某个数的特定点记为边缘。 Sobel 算子在 Prewitt 算子的基础上增加了权重的概念,认为相
邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越
大,从而实现图像锐化并突出边缘轮廓。当对精度要求不是很高时, Sobel 算子是一种较为
常用的边缘检测方法,其卷积模板如下所示:

2.2.频域

3.图像平滑

图像平滑是对图像作低通滤波,可在空间域或频率域实现。

3.1.空域

平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是模糊;另一类是消除噪音。空间域的平滑滤波一般采用简单平均法进行,就是求邻近像元点的平均亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。
1)均值滤波
OpenCV 中均值模板可以用 cv2.blur 和 cv2.boxFilter 函数实现。其基本用法如下:
blur = cv2.blur(img, (3, 5)) # 模板大小为 3*5, 模板的大小是可以设定的
box = cv2.boxFilter(img, -1, (3, 5))
(2 )高斯滤波
Opencv 中使用 cv2.GaussianBlur()函数实现高斯模糊。其基本用法如下:
blur = cv2.GaussianBlur(img, (5, 5), 0) # (5,5)表示的是卷积模板的大小,0 表示的是
沿 x 与 y 方向上的标准差
(3 )中值滤波
Opencv 用 cv2.medianBlur()函数实现中值滤波。其基本用法如下:
blur = cv2.medianBlur(img, 5 )

3.2.频域

三、实验内容、核心算法/代码及结果

1.绘制灰度图像直方图并对直方图均衡化

    # 灰度直方图

    img_GRAY = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

    cv.imshow("gray", img_GRAY)

    cv.waitKey(0)

    # 绘制直方图

    hist_ori = cv.calcHist([img_GRAY], [0], None, [256], [0, 255])

    plt.figure()

    plt.plot(hist_ori)

    # 进行直方图均衡化。

    equ = cv.equalizeHist(img_GRAY)

    cv.imshow("equ", equ)

    cv.waitKey(0)

    cv.destroyAllWindows()

    hist_equ = cv.calcHist([equ], [0], None, [256], [0, 255])

    plt.figure()

    plt.plot(hist_equ)

    plt.show()

2.利用模版进行空域滤波

    # 空域中的平滑滤波

    img_GRAY = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

    # 进行均值滤波

    # 模板大小为 3*5, 模板的大小是可以设定的

    blur_mean = cv.blur(img_GRAY, (3, 5))

    box_mean = cv.boxFilter(img_GRAY, -1, (3, 5))

    cv.imshow("blur_mean", blur_mean)

    cv.waitKey(0)

    cv.imshow("box_mean", box_mean)

    cv.waitKey(0)

    # 进行高斯模糊滤波

    # (5,5)表示的是卷积模板的大小,0 表示的是沿 x 与 y 方向上的标准差

    blur_gauss = cv.GaussianBlur(img_GRAY, (5, 5), 0)

    cv.imshow("blur_gauss", blur_gauss)

    cv.waitKey(0)

    # 进行中值滤波

    # 5 表示的是卷积模板的大小

    blur_mid = cv.medianBlur(img_GRAY, 5)

    cv.imshow("blur_mid", blur_mid)

    cv.waitKey(0)

    # 空域中的锐化滤波

    img_GRAY = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

    # Roberts 算子

    # 图像高斯滤波去噪

    blur = cv.GaussianBlur(img_GRAY, (3, 3), 1, 1)  # 核尺寸通过对图像的调节自行定义

    # 图像阈值化处理

    ret, thresh = cv.threshold(blur, 127, 255, cv.THRESH_BINARY)  # 二进制阈值化

    # 调用 Roberts 算法的 OpenCV 库函数进行图像轮廓提取

    R_kernelx = np.array([[-1, 0], [0, 1]], dtype=int)

    R_kernely = np.array([[0, -1], [1, 0]], dtype=int)

    R_x = cv.filter2D(thresh, cv.CV_16S, R_kernelx)

    R_y = cv.filter2D(thresh, cv.CV_16S, R_kernely)

    # 转 uint8

    R_absX = cv.convertScaleAbs(R_x)

    R_absY = cv.convertScaleAbs(R_y)

    Roberts = cv.addWeighted(R_absX, 0.5, R_absY, 0.5, 0)

    cv.imshow("Roberts", Roberts)

    cv.waitKey()

    # Prewitt 算子

    P_S_kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)

    P_S_kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)

    P_x = cv.filter2D(thresh, -1, P_S_kernelx)

    P_y = cv.filter2D(thresh, -1, P_S_kernely)

    P_absX = cv.convertScaleAbs(P_x)

    P_absY = cv.convertScaleAbs(P_y)

    Prewitt = cv.addWeighted(P_absX, 0.5, P_absY, 0.5, 0)

    cv.imshow("Prewitt", Prewitt)

    cv.waitKey()

    # Sobel 算子

    S_x = cv.Sobel(thresh, cv.CV_16S, 1, 0)  # 对 x 求一阶导

    S_y = cv.Sobel(thresh, cv.CV_16S, 0, 1)  # 对 y 求一阶导

    S_absX = cv.convertScaleAbs(S_x)  # 对 x 取绝对值,并将图像转换为 8 位图

    S_absY = cv.convertScaleAbs(S_y)  # 对 y 取绝对值,并将图像转换为 8 位图

    Sobel = cv.addWeighted(S_absX, 0.5, S_absY, 0.5, 0)

    cv.imshow("Sobel", Sobel)

    cv.waitKey()

3.分别利用常见低通(平滑)滤波器与高通(锐化)滤波器进行频域滤波

    # 频域中的低通(平滑)滤波器

    img_GRAY = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

    # 傅里叶变换

    img_dft = np.fft.fft2(img_GRAY)

    dft_shift = np.fft.fftshift(img_dft)

    # 低通滤波

    h, w = dft_shift.shape[0:2]

    h_center, w_center = int(h / 2), int(w / 2)

    dft_shift_black = np.zeros((h, w), np.uint8)

    # 中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为1,保留低频部分

    dft_shift_black[

        h_center - int(size / 2) : h_center + int(size / 2),

        w_center - int(size / 2) : w_center + int(size / 2),

    ] = 1

    dft_shift = dft_shift * dft_shift_black  # 将定义的低通滤波与传入的傅里叶频谱图一一对应相乘,得到低通滤波

    res = np.log(np.abs(dft_shift))

    # 傅里叶逆变换

    idft_shift = np.fft.ifftshift(dft_shift)

    ifimg = np.fft.ifft2(idft_shift)

    ifimg = np.abs(ifimg)

    cv.imshow("lowPassFilter", np.int8(ifimg))

    cv.waitKey(0)

    # 频域中的高通(锐化)滤波器

    img_GRAY = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

    # 傅里叶变换

    img_dft = np.fft.fft2(img_GRAY)

    dft_shift = np.fft.fftshift(img_dft)  # 将频域从左上角移动到中间

    # 高通滤波

    h, w = dft_shift.shape[0:2]  # 获取图像属性(高、宽和图像通道数)

    h_center, w_center = int(h / 2), int(w / 2)  # 找到傅里叶频谱图的中心点

    # 中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为0

    dft_shift[

        h_center - int(size / 2) : h_center + int(size / 2),

        w_center - int(size / 2) : w_center + int(size / 2),

    ] = 0

    res = np.log(np.abs(dft_shift))

    # 傅里叶逆变换

    idft_shift = np.fft.ifftshift(dft_shift)  # 将频域从中间移动到左上角

    img_idft = np.fft.ifft2(idft_shift)

    img_idft = np.abs(img_idft)

    cv.imshow("highPassFilter", np.int8(img_idft))

    cv.waitKey(0)

 完整代码在FchZero/Digita_Image_Processing_Experiment (github.com) 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FchZero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值