tnblog
首页
视频
资源
登录

OpenCV 直方图与傅里叶变换(学习笔记)

1930人阅读 2024/1/23 11:48 总访问:3511499 评论:0 收藏:0 手机
分类: opencv

OpenCV 直方图与傅里叶变换(学习笔记)

直方图


直方图是一种统计图表,用于展示数据的分布情况。
这里将展示图片中直方图,把每一个像素点作为展示。

初始化

  1. import cv2 #opencv读取的格式是BGR
  2. import numpy as np
  3. import matplotlib.pyplot as plt#Matplotlib是RGB
  4. %matplotlib inline
  1. def cv_show(img,name):
  2. cv2.imshow(name,img)
  3. cv2.waitKey()
  4. cv2.destroyAllWindows()

示例代码


直方图主要调用的方法是cv2.calcHist(images,channels,mask,histSize,ranges)

参数 描述
images 原图像图像格式为 uint8 或 ?oat32。当传入函数时应 用中括号 [] 括来例如[img]
channels 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的参数可以是 [0][1][2] 它们分别对应着 BGR。
mask 掩模图像。统整幅图像的直方图就把它为 None。但是如果你想统图像某一分的直方图的你就制作一个掩模图像并使用它。
histSize BIN的数目。也应用中括号括来
ranges 像素值范围常为 [0256]
  1. img = cv2.imread('cat.jpg',0) #0表示灰度图
  2. hist = cv2.calcHist([img],[0],None,[256],[0,256])
  3. hist.shape

(256, 1)

  1. plt.hist(img.ravel(),256);
  2. plt.show()

  1. img = cv2.imread('cat.jpg')
  2. color = ('b','g','r')
  3. for i,col in enumerate(color):
  4. histr = cv2.calcHist([img],[i],None,[256],[0,256])
  5. plt.plot(histr,color = col)
  6. plt.xlim([0,256])


通过以上操作我们看到了这张照片特定颜色的分布情况。
但是如果我们想关注具体那一部分的颜色信息我们就需要使用mask这个东西。

mask操作

  1. # 创建mast
  2. mask = np.zeros(img.shape[:2], np.uint8)
  3. print (mask.shape) # 维度
  4. mask[100:300, 100:400] = 255
  5. cv_show(mask,'mask')

(414, 500)


接下来我们通过mask对中间图片白框范围的小猫做一个直方图

  1. img = cv2.imread('cat.jpg', 0)
  2. cv_show(img,'img')

  1. masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作
  2. cv_show(masked_img,'masked_img')

  1. hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
  2. hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])
  1. plt.subplot(221), plt.imshow(img, 'gray')
  2. plt.subplot(222), plt.imshow(mask, 'gray')
  3. plt.subplot(223), plt.imshow(masked_img, 'gray')
  4. plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
  5. plt.xlim([0, 256])
  6. plt.show()

直方图均衡化


直方图均衡化是一种用于改善图片处理的技术,特别是在图像背景和前景都很暗的情况下。
这个方法通常用来增强医学和卫星图像的对比度,但也可以用于任何类型的图像。


加载原始图像。

  1. img = cv2.imread('clahe.jpg',0) #0表示灰度图 #clahe
  2. plt.hist(img.ravel(),256);
  3. plt.show()


进行直方图均值化。

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


我们发现它产生了很多缝隙。
接下来我们查看一下两张图片的差异。

  1. res = np.hstack((img,equ))
  2. cv_show(res,'res')


发现比以前的要亮了很多。

自适应直方图均衡化


它是直方图均衡化的一种改进方法,它对一小部分一小部分进行均衡化,不像直方图全局均衡化。

  1. clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
  2. res_clahe = clahe.apply(img)
  3. res = np.hstack((img,equ,res_clahe)) # 三张图做对比
  4. cv_show(res,'res')


发现自适应直方图均衡化比直方图均衡化要写实很多。

傅里叶变换


简单来讲,傅里叶变换换就是一种把复杂信号分解成简单波形的方法,让我们能更容易地理解和处理这些信号。
更多请参考:https://zhuanlan.zhihu.com/p/19763358

傅里叶变换的作用


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

滤波


低通滤波器:只保留低频,会使得图像模糊
高通滤波器:只保留高频,会使得图像细节增强
opencv中主要就是cv2.dft()cv2.idft(),输入图像需要先转换成np.float32 格式。
得到的结果中频率为0的部分会在左上角,通常要转换到中心位置,可以通过shift变换来实现。
cv2.dft()返回的结果是双通道的(实部,虚部),通常还需要转换成图像格式才能展示(0,255)。

  1. import numpy as np
  2. import cv2
  3. from matplotlib import pyplot as plt
  4. img = cv2.imread('lena.jpg',0)
  5. img_float32 = np.float32(img)
  6. # 进行傅里叶变换
  7. dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
  8. # 把频率域数据移会原来的位置
  9. dft_shift = np.fft.fftshift(dft)
  10. # 得到灰度图能表示的形式
  11. magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
  12. plt.subplot(121),plt.imshow(img, cmap = 'gray')
  13. plt.title('Input Image'), plt.xticks([]), plt.yticks([])
  14. plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
  15. plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
  16. plt.show()

  1. import numpy as np
  2. import cv2
  3. from matplotlib import pyplot as plt
  4. # 读取图像,0 表示以灰度模式
  5. img = cv2.imread('lena.jpg', 0)
  6. # 将图像转换为32位浮点数类型
  7. img_float32 = np.float32(img)
  8. # 使用cv2.dft进行傅立叶变换,并使用cv2.DFT_COMPLEX_OUTPUT标志返回复数结果
  9. dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
  10. # 将傅立叶变换的结果中心移动到图像中心
  11. dft_shift = np.fft.fftshift(dft)
  12. # 获取图像的行数和列数
  13. rows, cols = img.shape
  14. # 计算图像中心点
  15. crow, ccol = int(rows / 2), int(cols / 2)
  16. # 创建一个低通滤波器掩码,初始时全为0
  17. mask = np.zeros((rows, cols, 2), np.uint8)
  18. # 将掩码中心部分设置为1(30x30区域),其余为0
  19. mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
  20. # 将傅立叶变换结果与低通滤波器掩码相乘,实现低通滤波
  21. fshift = dft_shift * mask
  22. # 使用ifftshift将中心移回原位
  23. f_ishift = np.fft.ifftshift(fshift)
  24. # 应用逆傅立叶变换(IDFT)
  25. img_back = cv2.idft(f_ishift)
  26. # 将复数转换为幅度,用于显示结果
  27. img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
  28. # 使用matplotlib显示原始图像和滤波后的图像
  29. plt.subplot(121), plt.imshow(img, cmap='gray')
  30. plt.title('Input Image'), plt.xticks([]), plt.yticks([])
  31. plt.subplot(122), plt.imshow(img_back, cmap='gray')
  32. plt.title('Result'), plt.xticks([]), plt.yticks([])
  33. plt.show() # 显示图像

  1. # 导入必要的库
  2. import numpy as np
  3. import cv2
  4. from matplotlib import pyplot as plt
  5. # 读取图像,0 表示以灰度模式
  6. img = cv2.imread('lena.jpg', 0)
  7. # 将图像转换为32位浮点数类型
  8. img_float32 = np.float32(img)
  9. # 使用cv2.dft进行傅立叶变换,并使用cv2.DFT_COMPLEX_OUTPUT标志返回复数结果
  10. dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
  11. # 将傅立叶变换的结果中心移动到图像中心
  12. dft_shift = np.fft.fftshift(dft)
  13. # 获取图像的行数和列数
  14. rows, cols = img.shape
  15. # 计算图像中心点
  16. crow, ccol = int(rows / 2), int(cols / 2) # 中心位置
  17. # 创建一个高通滤波器掩码,初始时全为1
  18. mask = np.ones((rows, cols, 2), np.uint8)
  19. # 将掩码中心部分设置为0(30x30区域),其余为1
  20. mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0
  21. # 将傅立叶变换结果与高通滤波器掩码相乘,实现高通滤波
  22. fshift = dft_shift * mask
  23. # 使用ifftshift将中心移回原位
  24. f_ishift = np.fft.ifftshift(fshift)
  25. # 应用逆傅立叶变换(IDFT)
  26. img_back = cv2.idft(f_ishift)
  27. # 将复数转换为幅度,用于显示结果
  28. img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
  29. # 使用matplotlib显示原始图像和滤波后的图像
  30. plt.subplot(121), plt.imshow(img, cmap='gray')
  31. plt.title('Input Image'), plt.xticks([]), plt.yticks([])
  32. plt.subplot(122), plt.imshow(img_back, cmap='gray')
  33. plt.title('Result'), plt.xticks([]), plt.yticks([])
  34. plt.show() # 显示图像


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

OpenCV 简介与安装

OpenCV 简介与安装[TOC] OpenCV 简介OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库。安...

OpenCV 图像基本操作(学习笔记)

OpenCV 图像基本操作(学习笔记)[TOC] 在一张图像中,每取出一个像素块会分成红绿蓝三种颜色通道,每一种颜色通道都是一...

OpenCV 图像处理(学习笔记)

OpenCV 图像处理(学习笔记)[TOC] 灰度图import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pypl...

OpenCV 图像梯度计算(学习笔记)

OpenCV 图像梯度计算(学习笔记)[TOC] Sobel算子简介Sobel算子是一个图像边缘检测的算法。其基本原理是通过计算像素点梯度...

OpenCV Canny边缘检测(学习笔记)

OpenCV Canny边缘检测(学习笔记)[TOC] Canny边缘检测Canny边缘检测主要是按照如下步骤来进行的边缘检测:1.使用高斯滤波器...

OpenCV 图像金字塔、轮廓与模板匹配(学习笔记)

OpenCV 图像金字塔、轮廓与模板匹配(学习笔记)[TOC] 图像金字塔初始化代码。import cv2 #opencv读取的格式是BGR import n...
这一世以无限游戏为使命!
排名
2
文章
642
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术