ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

OpenCV计算机视觉实战(Python)_08-直方图与傅里叶变换

2021-08-07 10:34:10  阅读:192  来源: 互联网

标签:plt img Python mask 08 cv2 直方图 np 256


什么是histogram?

  • 它可以给出图像的密度分布的总体概念,它的x轴是像素值(0到255)y轴是对应的像素在图像里的数量。
  • 看histogram你可以得到对比度,亮度,密度分布等直观信息。今天的所有图像处理工具都提供了histogram属性,

1. 直方图

直方图

OpenCV代码: cv2.calcHist(image, channels, mask, histSize, ranges)

  • images: 原图像图像格式为uint8或float32,当传入函数时,应用中括号[]来表示,例如[img]
  • channels: 同样用[]来表示,如果图像时灰度图,那么它的值就是[0],如果是彩色图像,那么传入的参数可以是0,1,2,它们分别对应着RGB
    • [0],[1]和[2]来分别计算蓝色,绿色和红色通道的histogram。
  • mask: 掩模图像,如果想统计整幅图中的直方图就把它写为None,如果想统计某一部分的直方图,就制作一个掩模图像并使用它。
  • histSize:BIN的数目,也应该用中括号表示 (需要用户方括号传入),对于全刻度,我们传入[256].
  • ranges:像素值范围常为[0,256] (RANGE,一般来说是[0,256])

In [3]:

import cv2 
img = cv2.imread("D:/WeChat.picture/cat.jpg",0)  # 0 表示转为 灰度图
hist = cv2.calcHist([img] , [0] , None ,[256] ,[0,256])          #None 表示 没掩盖 对整个图进行处理
hist.shape   # 结果显示出可能有256 个 取值 , 1 表示 2维 统计出现个数

Out[3]:

(256, 1)

In [8]:

# opencv  是 (B G R)的形式 , matplotlib 是 (R B G) 的形式 可用 ravel 转化
import matplotlib.pyplot as plt
plt.hist(img.ravel() , 256)    # plt.hist(img.ravel() , 16) 将其 别分为 16 区间  
plt.show()

In [5]:

cv2.imshow("img" , img)
cv2.waitKey(0)
cv2.destroyAllWindows()

In [9]:

img = cv2.imread("D:/WeChat.picture/cat.jpg")
color =  ('b', 'g' ,'r')
for i, col in enumerate (color):
    histr = cv2 .calcHist([img] , [i] , None , [256] , [0,256])
    plt.plot(histr , color = col)   # 画线
    plt.xlim([0,256])   #表示 [ 0 ,x] 表示 x的区间 , 并 建立一个坐标 (第一象限)

#  三个颜色通道在直方图的统计结果

直方图均衡化

mask创建 (掩码) mask = np.zeros(img , shape[:2] , np.uint8)

In [22]:

def cv_show(img , name):
    cv2.imshow(name , img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
import numpy as np
import cv2
img = cv2.imread("D:/WeChat.picture/cat.jpg",0)
mask = np.zeros(img.shape[:2],np.uint8)  
print(img.shape)
mask [100:300 ,100:400] = 255
cv_show(mask , "mask")
mask_img = cv2.bitwise_and(img , img , mask =mask) #与操作
cv_show(mask_img ,"mask_img")
(414, 500)

In [23]:

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

plt.imshow()函数负责对图像进行处理,并显示其格式,而plt.show()则是将plt.imshow()处理后的函数显示出来。

In [20]:

# 使用plt.subplot来创建小图. plt.subplot(221)表示将整个图像窗口分为2行2列, 当前位置为1.
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.show()

自适应直方图均衡化

In [24]:

import cv2
import matplotlib.pyplot as plt
img = cv2.imread("D:/WeChat.picture/clahe.jpg",0)
hist = cv2.calcHist([img] , [0] ,None , [256] ,[0 ,256])
plt.hist(img.ravel() ,256)   # number 表示分为 多少部分, ravel   bgr 转为 rgb
plt.show()

In [135]:

equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(),256)
plt.show()

分小块进行直方图均衡化处理:

In [136]:

import numpy as np
res = np.hstack((img ,equ))  # 要求维度 一致 灰度为2维  彩色图为 3 维度
cv_show(res , "res")

自适直方图均衡化

In [137]:

clahe = cv2.createCLAHE(clipLimit = 2.0 , tileGridSize = (8, 8))
res_clahe = clahe.apply(img)
res = np.hstack((img , equ ,res_clahe))
cv_show(res , "res")

2. 傅里叶变换

介绍

傅里叶变换:

将时域(以时间为主轴,在某个时间发生了什么事情) 转换为频域(只要知道发生了什么事就好,不管在哪个时间发生的,只考虑发生的事情和频率)

应用

傅里叶变换的作用:

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

滤波:

  • 低通滤波器:只保留低频,会使得图像模糊
  • 高通滤波器:只保留高频,会使得图像细节增强

OpenCV程序

步骤:

  • OpenCV中主要是cv2.dft() 和 cv2.idft(),输入图像需要先转换为np.float32格式
  • 得到的结果中频率为0的部分会再左上角,通常要转换到中心位置,可以通过shift变换来实现
  • cv2.dft()返回的结果是双通道的(实部,虚部),通常还需要转换为图像格式才能显示(0,255)

In [41]:

import numpy as np
import cv2 
import matplotlib.pyplot as plt
img = cv2.imread("D:/WeChat.picture/lena.png", 0)  # 需转化为灰度图 处理
# 转换为:float32
img_float32 = np.float32(img)  
# 转换到频域
dft = cv2.dft(img_float32 , flags = cv2.DFT_COMPLEX_OUTPUT)
# 平移到原点
dft_shift = np.fft.fftshift(dft)
# 得到灰度图能表示的形式     将实部和虚部转换为0-255之间的数值
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:,:,0] , dft_shift[:,:,1]))
# 画图
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 Sepctrum") , plt.xticks([]) , plt.yticks([])
plt.show()

In [61]:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:/WeChat.picture/lena.png" , 0)  
# 转换为:float32
img_float32 = np.float32(img)
# 转换到频域
dft = cv2.dft(img_float32 , flags =  cv2.DFT_COMPLEX_OUTPUT) # 不可省去 flags
# 平移到原点
dft_shift = np.fft.fftshift(dft)
# 计算中心位置
rows , cols = img.shape  # 灰度图
crow , ccol = int (rows/2) ,int (cols/2)
# 低通滤波:创建掩码,掩码大小与图像大小一致,保留的位置的边界扩大30,保证能包括所有要保留的区域
mask = np.zeros((rows ,cols ,2) , np.uint8)
 mask[crow-30 :crow+30 , ccol-30 :ccol +30] = 1
# IDFT
fshift = dft_shift * mask # 低通
#fshift = dft_shift*mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
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()                                        # 不可省去

In [ ]:

In [63]:

import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('D:/Wechat.picture/lena.png',0)
# 转换为:float32
img_float32 = np.float32(img)
# 转换到频域
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
# 平移到原点
dft_shift = np.fft.fftshift(dft)
# 计算中心位置
rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2)
# 高通滤波:创建掩码,掩码大小与图像大小一致,保留的位置的边界扩大30,保证能包括所有要保留的区域
mask = np.ones((rows,cols,2),np.uint8)            # mask = np.zeros((rows,cols,2),np.uint8) 修改 zeros
mask[crow-30:crow+30, ccol-30:ccol+30] = 0       #  mask[crow-30:crow+30, ccol-30:ccol+30] = 1  1 改为 0
# IDFT
fshift = dft_shift * mask # 高通
f_ishift = np.fft.ifftshift(fshift) # 逆变换
img_back = cv2.idft(f_ishift)
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()

标签:plt,img,Python,mask,08,cv2,直方图,np,256
来源: https://blog.csdn.net/maxkeren/article/details/119479555

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有