OpenCV图像处理笔记[09]
48. matplotlib pyplotshow函数的使用
- imshow
imshow ( X, cmap = None )
-
- x : 要绘制的图像
- cmap : colormap, 颜色色谱, 默认为RGBA(A) 颜色空间
-
显示问题
-
灰度图像
colormap, 颜色图谱,默认为RGB(A)颜色空间,使用参数
cmap = plt.cm.gray
-
彩色图像
colormap,颜色图谱,默认为RGB(A)颜色空间,如果使用opencv读入的图像,默认空间为BGR, 需要调整色彩空间为RGB
-
49. 直方图均衡化对比
在一个窗口内显示四个子窗口,显示原始图像,原始图像均衡化直方图等
import matplotlib.pyplot as plt
-
subplot
subplot ( nrows, ncols, plot_number )
- nrows : 行数
- ncols : 列数
- plot_number: 窗口序号
-
imshow
imshow ( X, cmap = None )
- x : 要绘制的图像
- cmap : colormap, 颜色色谱, 默认为RGBA(A) 颜色空间
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('image\\boat.bmp',cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.subplot(221)
plt.imshow(img.cmap = plt.cm.gray).plt.axis('off')
plt_subplot(222)
plt.imshow(equ.cmap = plt.cm.gray).plt.axis('off')
plt_subplot(223)
plt.hist(img.ravel(),256)
plt_subplot(224)
plt.hist(equ.ravel(),256)
50. 傅里叶变换的理论基础
-
时域角度
横坐标是时间
-
频域角度
横坐标是频率的倒数
-
任何连续周期信号,可以由一组适当的正弦曲线组合而成。——傅里叶
-
傅里叶变换:从时间角度看的信号可以转换为从频率角度看的信号,两者同时还是可逆的。
51.numpy实现傅里叶变换
numpy.fft.fft2
- 实现傅里叶变换
- 返回一个复数数组( complex ndarray )
numpy.fft.ffushift
- 将零频率分量转移到频谱中心
20*np.log(np.abs(fshift))
- 设置频谱的范围
- (给复数数组重新标定范围,设置区间,转换成灰度图像,映射到0~255之间)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
result = 20*np.log(np.abs(shift))
plt.subplot(121)
plt.imshow(img,cmap = 'gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(result, cmap = 'gray')
plt.title('result')
plt.axis('off')
plt.show()
-
注意
- 傅里叶得到低频、高频信息,针对低频、高频处理能够实现不同的目的。
- 傅里叶过程是可逆的,图像经过傅里叶变换、逆傅里叶变换后,能够恢复到原始图像
- 在频域对图像进行处理,在频域的处理会反映在逆变换的图像上
52. numpy实现逆傅里叶变换
numpy.fft.ifft2
- 实现逆傅里叶变换,返回一个复数数组(complex ndarray)
numpy.fft.ifftshifr
- fftshift函数的逆函数
- (将整个图像的低频移到左上角)
iimg = np.abs( 逆傅里叶变换结果 )
- 设置值的范围
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\boat.bmp',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f) #将低频移到中心
ishift = np.fft.ifftshift(fshift) #将中心移到左上角
iimg = np.fft.fft2(ishift) #返回的是复数,无法显示
iimg = np.abs(iimg) #转换为绝对值
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()
53. 高通滤波演示
-
低频、高频
- 低频对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频对应着广袤的颜色趋于一致的草原。
- 高频对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。例如,在一幅大草原的图像中,其中狮子的边缘等信息。
- 衰减高频而通过低频,低通滤波器,将模糊一幅图像。
- 衰减低频而通过高频,高通滤波器,将增强尖锐细节,但是会导致图像的对比度降低。
-
滤波
- 接受(通过)或者拒绝一定频率的分量
- 通过低频的滤波器称为低通滤波器
- 通过高频的滤波器称为高通滤波器
-
频域滤波
-
修改傅里叶变换以达到特殊目的,然后计算 IDFT 返回到图像域。
-
特殊目的: 图像增强、图像去噪、边缘检测、特征提取、压缩、加密等。
-
-
高通滤波器(去掉低频)
rows, cols = img.shape crow,ccol = int(rows/2),int(cols/2) fshift[crow - 30:corw + 30, ccol - 30:ccol + 30] = 0
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('image\\lena.bmp',0) f = np.fft.fft2(img) fshift = np.fft.fftshift(f) #将低频移到中心 rows, cols = img.shape crow,ccol = int(rows/2),int(cols/2) fshift[crow - 30:corw + 30, ccol - 30:ccol + 30] = 0 ishift = np.fft.ifftshift(fshift) #将中心移到左上角 iImg = np.fft.fft2(ishift) #返回的是复数,无法显示 iImg = np.abs(iImg) #转换为绝对值 plt.subplot(121),plt.imshow(img,cmap = 'gray') plt.title('original'),plt.axis('off') plt.subplot(122),plt.imshow(iimg, cmap = 'gray') plt.title('iimg'),plt.axis('off') plt.show()
54. OpenCV实现傅里叶变换
返回结果 = cv2.dft(原始图像, 转换标识)
- 返回结果
- 是双通道的
- 第1个通道是结果的实数部分
- 第2个通道是结果的虚数部分
- 原始图像: 输入图像要首先转换成np.float32格式。 np.float32(img)
- 转换标识: flags = cv2.DFT_COMPLEX_OUTPUT, 输出一个复数阵列。
返回值 = cv2.magnitude( 参数1, 参数2 )
-
计算幅值
-
参数1: 浮点型X坐标值, 也就是实部
-
参数2: 浮点型Y坐标值, 也就是虚部
$dst( I ) = \sqrt{x(I) ^2 + y( I ) ^2} $
-
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) #傅里叶变换
dfshift = np.fft.fftshift(dft) #平移
result = 20*np.log(cv2.magnitude( dftShift[:,:,0], dftShitft[:,:,1] )) #计算幅度
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('result'),plt.axis('off')
plt.show()
55. OpenCV实现逆傅里叶变换
返回结果 = cv2.idft( 原始数据 )
- 返回结果: 取决于原始数据的类型和大小
- 原始数据: 实数或复数均可
返回值 = cv2.magnitude ( 参数1, 参数2 )
- 计算幅值
- 参数1: 浮点型X坐标值, 也就是实部
- 参数2: 浮点型Y坐标值, 也就是虚部
$dst( I ) = \sqrt{x(I) ^2 + y( I ) ^2} $
numpy.fft.ifftshift
- fftshift函数的逆函数
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) #傅里叶变换
dfshift = np.fft.fftshift(dft) #平移
ishift = np.fft.ifftshift(dfshift) #移动
iImg = cv2.idft(ishift)
iImg = cv2.magnitude( iImg[:,:,0], iImg[:,:,1] )) #计算幅度
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('inverse'),plt.axis('off') # 显示逆变换结果
plt.show()
56. 低通滤波示例
低通滤波器 x 频谱图像 = 滤波结果图像
-
生成代码
rows, cols = img.shape crow,ccol = int(rows/2),int(cols/2) mask = np.zeros((rows, cols, 2), np.unit8) mask[crow - 30:corw + 30, ccol - 30:ccol + 30] = 1
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT) #傅里叶变换
dfshift = np.fft.fftshift(dft) #平移
rows, cols = img.shape
crow,ccol = int(rows/2),int(cols/2)
mask = np.zeros((rows, cols, 2), np.unit8) #构造掩膜图像
fshift[crow - 30:corw + 30, ccol - 30:ccol + 30] = 1
fShift = dftShift*mask #滤波
ishift = np.fft.ifftshift(fShift) #将中心移到左上角
iImg = cv2.idft(ishift) #返回的是复数,无法显示
iImg = cv2.magnitude( iImg[:,:,0], iImg[:,:,1] ) #计算幅度
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()