2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 数字图像处理——实验二 数字图像增强实验

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

时间:2019-03-18 14:41:41

相关推荐

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

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

一、实验目的二、实验主要仪器设备三、实验原理四、实验内容及代码4.1 实验内容4.2 实验数据4.3 实验代码4.3.1 绘制灰度直方图4.3.2 对灰度图像进行直方图均衡化4.3.3 利用模板进行空域滤波4.3.4 利用低通(平滑)滤波器和高通(锐化)滤波器进行频域滤波 附录:整体代码

一、实验目的

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

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

二、实验主要仪器设备

(1)计算机;

(2)Python 3.x及PyCharm软件;

(3)典型的灰度、彩色图像文件。

注:opencv-python使用的是3.x 版本

三、实验原理

图像增强是指按特定的需要突出一幅图像中的某些信息,同时消弱或去除某些不需要的信息的处理方法。其主要目的是处理后的图像对某些特定的应用比原来的图像更加有效。图像增强技术主要有直方图修改处理、图像平滑化处理、图像尖锐化处理和彩色处理技术等。本实验以直方图均衡化增强图像对比度的方法为主要内容。

(1) 直方图

直方图是多种空间域处理技术的基础。直方图操作能有效地用于图像增强。除了提供有用的图像统计资料外,直方图固有的信息在其他图像处理应用中也是非常有用的,如图像压缩与分割。直方图在软件中易于计算,也适用于商用硬件设备,因此,它们成为了实时图像处理的一个流行工具。

直方图是图像的最基本的统计特征,它反映的是图像的灰度值的分布情况。直方图均衡化的目的是使图像在整个灰度值动态变化范围内的分布均匀化,改善图像的亮度分布状态,增强图像的视觉效果。灰度直方图是图像预处理中涉及最广泛的基本概念之一。

图像的直方图事实上就是图像的亮度分布的概率密度函数,是一幅图像的所有象素集合的最基本的统计规律。直方图反映了图像的明暗分布规律,可以通过图像变换进行直方图调整,获得较好的视觉效果。

直方图均衡化是通过灰度变换将一幅图像转换为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象素点数的过程。

(2) 图像锐化

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

(3) 图像平滑

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

四、实验内容及代码

4.1 实验内容

(1)绘制灰度图像直方图;

(2)对直方图均衡化;

(3)利用模板进行空域滤波;

(4)分别利用常见的低通(平滑)滤波器和高通(锐化)滤波器进行频率域滤波。

4.2 实验数据

本实验使用的图片同实验一,原始图片如图1所示:

图1. 原始图像

4.3 实验代码

4.3.1 绘制灰度直方图

cv2.calcHist()函数可以帮助我们通过直方图对整个图像的灰度分布有所了解,具体的使用参见博客:opencv学习笔记十七:直方图和直方图均衡化(cv2.calcHist、 cv2.equalizeHist)_耐心的小黑的博客-CSDN博客_cv2直方图均衡

实现代码:

import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread(r'./data/1.jpg') # 使用 imread 函数读取图像,并以 numpy 数组形式储存img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 使用 cv.cvtColor 函数转换色彩空间,从RGB空间转换到灰度空间# 1.绘制灰度直方图hist = cv2.calcHist([img_gray], [0], None, [256], [0, 255]) # OpenCV 利用 calcHist() 函数来绘制直方图plt.plot(hist)plt.show()

灰度图像及其灰度直方图:

图2(a). 灰度图像图2(b). 灰度直方图

4.3.2 对灰度图像进行直方图均衡化

实现代码:

# 2.直方图均衡化img_equ = cv2.equalizeHist(img_gray) # equalizeHist()函数输入为灰度图像,输出为直方图均衡化后的图像cv2.imshow('img_gray_equ', img_equ)cv2.waitKey(0)cv2.destroyAllWindows()hist_equ = cv2.calcHist([img_equ], [0], None, [256], [0, 255])plt.plot(hist_equ)plt.show()

直方图均衡化之后的效果:

图3(a). 直方图均衡化后的图像图3(b). 直方图均衡化后的灰度直方图

4.3.3 利用模板进行空域滤波

(1) 平滑滤波

实现代码:

# 3.利用模板进行空域滤波# 3.1 平滑滤波# 均值滤波img_blur = cv2.blur(img, (3, 5)) # 模板大小为 3*5, 其大小是可以设定的cv2.imshow('img_blur', img_blur)cv2.waitKey(0)cv2.destroyAllWindows()img_box = cv2.boxFilter(img, -1, (3, 5)) # 方框滤波cv2.imshow('img_box', img_box)cv2.waitKey(0)cv2.destroyAllWindows()# 高斯模糊滤波img_gauss = cv2.GaussianBlur(img, (5, 5), 0) # (5,5)表示的是卷积模板的大小,0 表示的是沿 x 与 y 方向上的标准差cv2.imshow('img_gauss', img_gauss)cv2.waitKey(0)cv2.destroyAllWindows()# 中值滤波img_median = cv2.medianBlur(img, 5)cv2.imshow('img_median', img_median)cv2.waitKey(0)cv2.destroyAllWindows()

三种平滑滤波后的效果图:

均值滤波图4(a). 3*5的模板进行均值滤波图4(b). 方框均值滤波(cv2.boxFilter()函数)高斯模糊滤波图5. 高斯模糊滤波效果中值滤波图6. 中值滤波效果

(2) 锐化滤波

实现代码:

# 3.2 锐化滤波# 3.2.1 Roberts算子(交叉微分算法)# 图像阈值化处理ret, img_binary = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) # 二进制阈值化# 调用Roberts算法的OpenCV库函数进行图像轮廓提取kernelx_Robert = np.array([[-1, 0], [0, 1]], dtype=int)kernely_Robert = np.array([[0, -1], [1, 0]], dtype=int)x_Robert = cv2.filter2D(img_binary, cv2.CV_16S, kernelx_Robert)y_Robert = cv2.filter2D(img_binary, cv2.CV_16S, kernely_Robert)# 转uint8absX_Robert = cv2.convertScaleAbs(x_Robert)absY_Robert = cv2.convertScaleAbs(y_Robert)img_Roberts = cv2.addWeighted(absX_Robert, 0.5, absY_Robert, 0.5, 0)# 展示处理后的结果cv2.imshow("img_Roberts", img_Roberts)cv2.waitKey(0)cv2.destroyAllWindows()# 3.2.2 Prewitt算子kernelx_Prewitt = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)kernely_Prewitt = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)x_Prewitt = cv2.filter2D(img_binary, -1, kernelx_Prewitt)y_Prewitt = cv2.filter2D(img_binary, -1, kernely_Prewitt)absX_Prewitt = cv2.convertScaleAbs(x_Prewitt)absY_Prewitt = cv2.convertScaleAbs(y_Prewitt)img_Prewitt = cv2.addWeighted(absX_Prewitt, 0.5, absY_Prewitt, 0.5, 0)cv2.imshow("img_Prewitt", img_Prewitt)cv2.waitKey(0)cv2.destroyAllWindows()# 3.2.3 Sobel算子(用于边缘检测的离散微分算子)x_Sobel = cv2.Sobel(img_binary, cv2.CV_16S, 1, 0) # 对x求一阶导y_Sobel = cv2.Sobel(img_binary, cv2.CV_16S, 0, 1)absX_Sobel = cv2.convertScaleAbs(x_Sobel) # 对x取绝对值,并将图像转换为8位图absY_Sobel = cv2.convertScaleAbs(y_Sobel)img_Sobel = cv2.addWeighted(absX_Sobel, 0.5, absY_Sobel, 0.5, 0)cv2.imshow("img2_Sobel.jpg", img_Sobel)cv2.waitKey(0)cv2.destroyAllWindows()

三种锐化滤波后的效果图:

Roberts算子图7. Roberts算子滤波效果图Prewitt算子图8. Prewitt算子滤波效果图Sobel算子图9. Sobel算子滤波效果图

4.3.4 利用低通(平滑)滤波器和高通(锐化)滤波器进行频域滤波

实现代码:

# 4.利用低通(平滑)滤波器和高通(锐化)滤波器进行频域滤波# 4.1 低通滤波器def lowPassFiltering(input_img, size):h, w = input_img.shape[0:2]h_center, w_center = int(h / 2), int(w / 2)img_black = np.zeros((h, w), np.uint8)# 中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为1,保留低频部分img_black[h_center-int(size/2):h_center+int(size/2), w_center-int(size/2):w_center+int(size/2)] = 1output_img = input_img*img_black # 将定义的低通滤波与传入的傅里叶频谱图一一对应相乘,得到低通滤波return output_img# 傅里叶变换img_dft = np.fft.fft2(img_gray)dft_shift_low = np.fft.fftshift(img_dft)# 低通滤波dft_shift_low = lowPassFiltering(dft_shift_low, 100)res = np.log(np.abs(dft_shift_low))# 傅里叶逆变换idft_shift = np.fft.ifftshift(dft_shift_low)ifimg = np.fft.ifft2(idft_shift)ifimg = np.abs(ifimg)cv2.imshow("img_lowPassFilter", np.int8(ifimg))cv2.waitKey(0)cv2.destroyAllWindows()# 4.2 高通滤波器def highPassFiltering(input_img, size):# 传递参数为傅里叶变换后的频谱图和滤波尺寸h, w = input_img.shape[0:2]# 获取图像属性(高、宽和图像通道数)h_center, w_center = int(h/2), int(w/2)# 找到傅里叶频谱图的中心点output_img = input_img# 中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为0output_img[h_center-int(size/2):h_center+int(size/2), w_center-int(size/2):w_center+int(size/2)] = 0return output_img# 傅里叶变换img_dft = np.fft.fft2(img_gray)dft_shift = np.fft.fftshift(img_dft) # 将频域从左上角移动到中间# 高通滤波dft_shift = highPassFiltering(dft_shift, 50)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)cv2.imshow("img_highPassFilter", np.int8(img_idft))cv2.waitKey(0)cv2.destroyAllWindows()

两种滤波器频域滤波效果:

低通滤波器图10. 低通滤波器滤波效果图高通滤波器图11. 高通滤波器滤波效果图

附录:整体代码

import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread(r'./data/1.jpg') # 使用 imread 函数读取图像,并以 numpy 数组形式储存img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 使用 cv.cvtColor 函数转换色彩空间,从RGB空间转换到灰度空间# 1.绘制灰度直方图hist = cv2.calcHist([img_gray], [0], None, [256], [0, 255]) # OpenCV 利用 calcHist() 函数来绘制直方图plt.plot(hist)plt.show()# 2.直方图均衡化img_equ = cv2.equalizeHist(img_gray) # equalizeHist()函数输入为灰度图像,输出为直方图均衡化后的图像cv2.imshow('img_gray_equ', img_equ)cv2.waitKey(0)cv2.destroyAllWindows()hist_equ = cv2.calcHist([img_equ], [0], None, [256], [0, 255])plt.plot(hist_equ)plt.show()# 3.利用模板进行空域滤波# 3.1 平滑滤波# 均值滤波img_blur = cv2.blur(img, (3, 5)) # 模板大小为 3*5, 其大小是可以设定的cv2.imshow('img_blur', img_blur)cv2.waitKey(0)cv2.destroyAllWindows()img_box = cv2.boxFilter(img, -1, (3, 5)) # 方框滤波cv2.imshow('img_box', img_box)cv2.waitKey(0)cv2.destroyAllWindows()# 高斯模糊滤波img_gauss = cv2.GaussianBlur(img, (5, 5), 0) # (5,5)表示的是卷积模板的大小,0 表示的是沿 x 与 y 方向上的标准差cv2.imshow('img_gauss', img_gauss)cv2.waitKey(0)cv2.destroyAllWindows()# 中值滤波img_median = cv2.medianBlur(img, 5)cv2.imshow('img_median', img_median)cv2.waitKey(0)cv2.destroyAllWindows()# 3.2 锐化滤波# 3.2.1 Roberts算子(交叉微分算法)# 图像阈值化处理ret, img_binary = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) # 二进制阈值化# 调用Roberts算法的OpenCV库函数进行图像轮廓提取kernelx_Robert = np.array([[-1, 0], [0, 1]], dtype=int)kernely_Robert = np.array([[0, -1], [1, 0]], dtype=int)x_Robert = cv2.filter2D(img_binary, cv2.CV_16S, kernelx_Robert)y_Robert = cv2.filter2D(img_binary, cv2.CV_16S, kernely_Robert)# 转uint8absX_Robert = cv2.convertScaleAbs(x_Robert)absY_Robert = cv2.convertScaleAbs(y_Robert)img_Roberts = cv2.addWeighted(absX_Robert, 0.5, absY_Robert, 0.5, 0)# 展示处理后的结果cv2.imshow("img_Roberts", img_Roberts)cv2.waitKey(0)cv2.destroyAllWindows()# 3.2.2 Prewitt算子kernelx_Prewitt = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)kernely_Prewitt = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)x_Prewitt = cv2.filter2D(img_binary, -1, kernelx_Prewitt)y_Prewitt = cv2.filter2D(img_binary, -1, kernely_Prewitt)absX_Prewitt = cv2.convertScaleAbs(x_Prewitt)absY_Prewitt = cv2.convertScaleAbs(y_Prewitt)img_Prewitt = cv2.addWeighted(absX_Prewitt, 0.5, absY_Prewitt, 0.5, 0)cv2.imshow("img_Prewitt", img_Prewitt)cv2.waitKey(0)cv2.destroyAllWindows()# 3.2.3 Sobel算子(用于边缘检测的离散微分算子)x_Sobel = cv2.Sobel(img_binary, cv2.CV_16S, 1, 0) # 对x求一阶导y_Sobel = cv2.Sobel(img_binary, cv2.CV_16S, 0, 1)absX_Sobel = cv2.convertScaleAbs(x_Sobel) # 对x取绝对值,并将图像转换为8位图absY_Sobel = cv2.convertScaleAbs(y_Sobel)img_Sobel = cv2.addWeighted(absX_Sobel, 0.5, absY_Sobel, 0.5, 0)cv2.imshow("img2_Sobel.jpg", img_Sobel)cv2.waitKey(0)cv2.destroyAllWindows()# 4.利用低通(平滑)滤波器和高通(锐化)滤波器进行频域滤波# 4.1 低通滤波器def lowPassFiltering(input_img, size):h, w = input_img.shape[0:2]h_center, w_center = int(h / 2), int(w / 2)img_black = np.zeros((h, w), np.uint8)# 中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为1,保留低频部分img_black[h_center-int(size/2):h_center+int(size/2), w_center-int(size/2):w_center+int(size/2)] = 1output_img = input_img*img_black # 将定义的低通滤波与传入的傅里叶频谱图一一对应相乘,得到低通滤波return output_img# 傅里叶变换img_dft = np.fft.fft2(img_gray)dft_shift_low = np.fft.fftshift(img_dft)# 低通滤波dft_shift_low = lowPassFiltering(dft_shift_low, 100)res = np.log(np.abs(dft_shift_low))# 傅里叶逆变换idft_shift = np.fft.ifftshift(dft_shift_low)ifimg = np.fft.ifft2(idft_shift)ifimg = np.abs(ifimg)cv2.imshow("img_lowPassFilter", np.int8(ifimg))cv2.waitKey(0)cv2.destroyAllWindows()# 4.2 高通滤波器def highPassFiltering(input_img, size):# 传递参数为傅里叶变换后的频谱图和滤波尺寸h, w = input_img.shape[0:2]# 获取图像属性(高、宽和图像通道数)h_center, w_center = int(h/2), int(w/2)# 找到傅里叶频谱图的中心点output_img = input_img# 中心点加减滤波尺寸的一半,刚好形成一个定义尺寸的滤波大小,然后设置为0output_img[h_center-int(size/2):h_center+int(size/2), w_center-int(size/2):w_center+int(size/2)] = 0return output_img# 傅里叶变换img_dft = np.fft.fft2(img_gray)dft_shift = np.fft.fftshift(img_dft) # 将频域从左上角移动到中间# 高通滤波dft_shift = highPassFiltering(dft_shift, 50)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)cv2.imshow("img_highPassFilter", np.int8(img_idft))cv2.waitKey(0)cv2.destroyAllWindows()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。