OpenCV计算机视觉(5)——直方图和傅里叶变换

直方图(统计像素点值的数量)

 

 cv2.calcHist(images,channels,mask,histSize,ranges)

  • images:原图像格式为uint8或float32,当传入函数时应用中括号 [] 括住表示,例如[img]
  • channels:同样用[]括,它会告诉函数,我们统幅图像的直方图。如果传入图像是灰度图,它的值就是 [0] 如果是彩色图像的传入参数可以是 [0] [1] [2] 它们分别对应着R G B
  • mask:掩膜图像。统整幅图像的直方图就把它为None。但是如果你想统图像某一部分的直方图,你就制作一个掩膜图像,并使用它。
  • histSize:BIN 的数目。也应运用中括号,直方图多少个bin
  • ranges:像素值范围常为[0 256]
img = cv2.imread('./cat.jpg',0)
hist = cv2.calcHist([img], [0], None,[256], [0,256])
# [img] :传入图像, [0]:通道数只有1个,None:不用mask掩膜,[256]:BINS,[0,256]直方图范围
print(hist.shape)
 
plt.hist(img.ravel(), 256) # 注意matplot是RGB的,opencv是BGR的
plt.show()
 
 
img = cv2.imread('./cat.jpg')
color = ('b','g','r')
# 遍历颜色通道
for i ,col in enumerate(color): #col B G R
    histr = cv2.calcHist([img], [i], None,[256], [0,256])
# [img] :传入图像, [0]:通道数只有1个,None:不用mask掩膜,[256]:BINS,[0,256]直方图范围
 
    plt.hist( histr ,color = col) # 注意matplot是RGB的,opencv是BGR的
    plt.xlim([0,256])
plot.show()

mask操作

# 创建mask
mask = np.zeros(img.shape[:2], np.uint8) #np.uint8 无符号整型0-255
mask[100:300, 100:400] = 255 #mask范围保存部分为白色置为255,黑色0
cv_show(mask,'mask')

img = cv2.imread('./cat.jpg',0)
cv_show(img,'img')
 
mask_img = cv2.bitwise_and(img, img, mask=mask) # 与操作
cv_show(mask_img ,'mask_img')

 
hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])

plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask, 'gray')
plt.subplot(223), plt.imshow(mask_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)

plt.xlim([0, 256])
plt.show()

直方图均衡化

均衡化操作,就是将灰度直方图分布,根据函数映射成另一种形式,累计概率是,像素所占总体概率,再加上前面的像素的概率

累计概率*取值范围就是映射之后的灰度值,再取整。

均衡化效果

equ = cv2.equlizeHist(img)
plt.hist(equ.ravel(),255)
plt.show()
res = np.hstack((img, equ))
cv_show(res, 'res')

自适应直方图均衡化

分块做局部均衡化,可以更好的保留细节。

clche = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
res_clahe = clahe.apply(img)      #clahe 自适应直方图均衡化
res = np.hstack((img,equ,res_clahe))
cv_show(res,'res')

傅里叶变换

再生活中,按照时间为参照就是时域分析。频域上不变。

傅里叶变换的作用

  • 高频:变化剧烈的灰度分量,例如边界
  • 低频:变化缓慢的灰度分量,例如一片大海 

滤波

  • 低通滤波器:只保留低频,会使图像变得模糊(图像内部)
  • 高频滤波器:只保留高频,会使得图像细节增强(图像边缘,变化剧烈,为高频)
  • opencv中主要就是cv2.dif() 和cv2.idif() 【傅里叶逆变换】,输入图像需要先转换成np.float32 格式
  • 得到的结果中频率为0的部分会在左上角,通常要转换到中心位置,可以通过shift变换来实现
  • cv2.dif() 返回的结果是双通道的(实部,虚部),通常还需要转换成图像格式才能展示(0,255)
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 27 22:33:15 2019
@author: ZIXI
"""
 
 
import cv2
import numpy as np
import matplotlib.pyplot as plt
 
img = cv2.imread('F:/picture/img/lena.jpg',0)         #读灰度图
 
img_float32 = np.float32(img)
 
#执行傅里叶变换,
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
 
#numpy中有fft.shift操作,可以将得到的低频,拉到中间
dft_shift = np.fft.fftshift(dft)
 
#得到灰度图能表示的形式
magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
# 对两个通道进行操作,函数得出的数很小,在20np.log(),映射到0-255范围
 
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Input Image'),plt.xticks([]),plt.yticks([])#隐藏坐标轴
plt.subplot(122),plt.imshow(magnitude_spectrum,cmap = 'gray')
 
plt.title('Magnitude Spectrum'),plt.xticks([]),plt.yticks([])
plt.show()
 
 
 

中间亮的是低频分量,高频分量向四周发散。

# -*- coding: utf-8 -*-
"""
Created on Sun Jan 27 22:33:15 2019
@author: Zixi
"""
 
 
import cv2
import numpy as np
import matplotlib.pyplot as plt
    
img = cv2.imread('F:/picture/img/lena.jpg',0)         #读灰度图
 
img_float32 = np.float32(img)
 
#执行傅里叶变换,
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
 
#numpy中有fft.shift操作,可以将得到的低频,拉到中间
dft_shift = np.fft.fftshift(dft)
#得到灰度图能表示的形式
 
rows,cols = img.shape
crow,ccol = int(rows/2),int(cols/2) # 中心位置
 
#低通滤波
mask = np.zeros((rows,cols,2) ,np.uint8) #制定掩膜,大小和图像一样,np.zeros初始化
mask[crow-30:crow+30,ccol-30:ccol+30] = 1 #使中心位置,上下左右距离30,置为1
 
#DFT 
fshift = dft_shift*mask            #掩码与dft后结果相乘只保留出中间区域
f_ishift = np.fft.ifftshift(fshift) #执行idft逆变换之前,执行ishift,从中间再还到原来的位置
img_back = cv2.idft(f_ishift)       #执行idft,还原回去了
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1]) #实部虚部处理成图像格式
 
 
plt.subplot(121),plt.imshow(img,cmap = 'gray')  
plt.title('Input Image'),plt.xticks([]),plt.yticks([])#隐藏坐标轴
plt.subplot(122),plt.imshow(img_back,cmap = 'gray')
 
plt.title('result'),plt.xticks([]),plt.yticks([])
plt.show()
 
 
 

低通滤波器后变得模糊了

mask = np.ones((rows,cols,2) ,np.uint8) #制定掩膜,大小和图像一样,np.zeros初始化
mask[crow-30:crow+30,ccol-30:ccol+30] =0

在对图像处理时,想要更加高效,有层次,在频域处理效果更好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值