Python opencv图像处理基础总结(三) 图像直方图 直方图应用 直方图反向投影

简介: 图像直方图是反映一个图像像素分布的统计表,其横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。

一、图像直方图


画直方图要用到 matplotlib 库


图像直方图是反映一个图像像素分布的统计表,其横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征。直方图的显示方式是左暗又亮,左边用于描述图像的暗度,右边用于描述图像的亮度。


matplotlib.pyplot.hist函数绘制直方图


plt.hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, normed=None, hold=None, data=None, **kwargs)
  • x参数表示是一个数组或一个序列,是指定每个bin分布的数据。
  • bins参数表示指定bin的个数
  • range参数表示横坐标显示的范围,范围之外的将被舍弃。


cv2.calcHist(images, channels, mask, histSize, ranges, hist=None, accumulate=None)
  • images:输入图像
  • channels:传入图像的通道,如果是灰度图像,只有一个通道,值为0;如果是彩色图像(有3个通道),那么值为0、1、2中选择一个,对应着BGR各个通道,这个值也得用 [ ] 传入。
  • mask:表示掩膜图像,如果统计整幅图,那么为None;而如果要统计部分图的直方图,就得构造相应的掩膜来计算。
  • histSize:灰度级的个数,需要中括号,比如[256]。
  • ranges:像素值的范围,通常[0,256]。此外,假如channels为[0,1],ranges为[0,256,0,180],则代表0通道范围是0-256,1通道范围0-180。


importcv2ascvimportmatplotlib.pyplotaspltdefplot_hist(image):
# ravel函数将多维数组降为一维数组plt.hist(image.ravel(), 256, [0, 256])
image_hist(src)
plt.show()
defimage_hist(image):
colors= ['blue', 'green', 'red']
fori, colorinenumerate(colors):
# 三个通道hist=cv.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.show()
src=cv.imread(r'./test/004.jpg')
cv.imshow('src', src)
plot_hist(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:

opencv1.png



二、直方图应用


1. 直方图均衡化


直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法,是图像增强的一个手段。


直方图均衡化:如果一副图像的像素占有很多的灰度级而且分布均匀,那么这样的图像往往有高对比度和多变的灰度色调。直方图均衡化就是一种能仅靠输入图像直方图信息自动达到这种效果的变换函数。它的基本思想是对图像中像素个数多的灰度级进行展宽,而对图像中像素个数少的灰度进行压缩,从而扩展像元取值的动态范围,提高了对比度和灰度色调的变化,使图像更加清晰。


cv2.equalizeHist(src, dst=None)
# 函数equalizeHist的作用:直方图均衡化,提高图像质量。


importcv2ascv# 全局直方图均衡化可能得到是一种全局意义上的均衡化,但是有的时候这种操作并不是很好,会把某些不该调整的部分给调整了defequal_hist(image):
# 全局直方图均衡化  基于灰度图像  单通道gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst=cv.equalizeHist(gray)
cv.imshow('equal_image', dst)      # 增强图像对比度src=cv.imread(r'./test/013.png')
src=cv.resize(src, None, fx=0.5, fy=0.5)
cv.imshow('src', src)
equal_hist(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:

opencv2.png


cv2.createCLAHE(clipLimit=None, tileGridSize=None)


  • clipLimit:对比度的大小
  • tileGridSize:每次处理块的大小


importcv2ascv# 局部直方图均衡化,也就是是说把整个图像分成许多小块(比如按10*10作为一个小块),那么对每个小块进行均衡化defclache_demo(image):
# 局部直方图均衡化  基于灰度图像  局部增强对比度gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
clahe=cv.createCLAHE(clipLimit=2.0, tileGridSize=(10, 10))
dst=clahe.apply(gray)  # 将clahe这种局部直方图均衡化应用到灰度图graycv.imshow('clahe_image', dst)
src=cv.imread(r'./test/013.png')
src=cv.resize(src, None, fx=0.5, fy=0.5)
cv.imshow('src', src)
clache_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:

opencv3.png



2. 直方图比较


cv2.compareHist(H1, H2, method)


  • H1,H2:要比较的两张直方图
  • method:比较方法


比较方法(method)


  • 相关性比较 (method=cv2.HISTCMP_CORREL) 值越大,相关度越高,最大值为1,最小值为0。
  • 卡方比较(method=cv.HISTCMP_CHISQR 值越小,相关度越高,最大值无上界,最小值0。
  • 巴氏距离比较(method=cv.HISTCMP_BHATTACHARYYA) 值越小,相关度越高,最大值为1,最小值为0。


importcv2ascvimportnumpyasnpdefcreate_rgb_hist(image):
h, w, c=image.shape# 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵 # 16 ** 3 的意思为三通道每通道有16个binsrgb_hist=np.zeros([16**3, 1], np.float32)
bsize=256/16forrowinrange(h):
forcolinrange(w):
b=image[row, col, 0]
g=image[row, col, 1]
r=image[row, col, 2]
# 构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建index=np.int(b/bsize)*16*16+np.int(g/bsize)*16+np.int(r/bsize)
# 该处形成的矩阵即为直方图矩阵rgb_hist[np.int(index), 0] +=1returnrgb_histdefhist_compare(image1, image2):
# 第一幅图的rgb三通道直方图(直方图矩阵)hist1=create_rgb_hist(image1)
# 第二幅图的rgb三通道直方图(直方图矩阵)hist2=create_rgb_hist(image2)
# 三种方法比较match1=cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
match2=cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
match3=cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
print(f'巴氏距离:{match1}  相关性:{match2}   卡方:{match3}')
src1=cv.imread(r'./test/014.png')
src2=cv.imread(r'./test/006.png')
cv.imshow('src1', src1)
cv.imshow('src2', src2)
hist_compare(src1, src2)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:


巴氏距离:0.07197755337904468相关性:0.994234165782534卡方:15669.370232792859

opencv4.png


三、直方图反向投影


1. HSV和RGB色彩空间


importcv2ascvimportmatplotlib.pyplotaspltdefhist2D_demo(image):
hsv=cv.cvtColor(image, cv.COLOR_BGR2HSV)
hist=cv.calcHist([hsv], [0, 1], None, [32, 48], [0, 180, 0, 256])
# cv.imshow('hist2D', hist)plt.imshow(hist, interpolation='nearest')   # 插值方式   邻进点插值plt.title('2D hist')    # 2D直方图空间plt.show()
src=cv.imread(r'./test/004.jpg')
cv.imshow('src', src)
hist2D_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()


运行效果如下:

opencv5.png



2. 反向投影


直方图反向投影用于图像分割或查找图像中感兴趣的对象,简单来说,它会创建一个与输入图像大小相同(单个通道)的图像,其中每个像素对应于属于我们对象该像素的概率,输出图像将使我们感兴趣的对象比其余部分更明显。


首先,我们创建一个包含我们感兴趣对象的图像的直方图,对象应尽可能填充图像以获得更好的结果,颜色直方图比灰度直方图更受青睐,因为对象的颜色比灰度强度更能定义对象,然后我们将这个直方图反投影到我们需要找到对象的测试图像上。


cv2.normalize(src, dst, alpha=None, beta=None, norm_type=None, dtype=None, mask=None)


  • src:输入数组
  • dst:输出与src相同大小的数组,支持原地运算。
  • alpha:range normalization模式的最小值
  • beta:range normalization模式的最大值,不用于norm normalization(范数归一化)模式。
  • norm_type:归一化的类型


归一化类型


  • NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。
  • NORM_INF:归一化数组的C-范数(绝对值的最大值)
  • NORM_L1:归一化数组的L1-范数(绝对值的和)
  • NORM_L2:归一化数组的(欧几里德)L2-范数


cv2.calcBackProject(images, channels, hist, ranges, scale, dst=None)


  • images:输入图像(是HSV图像),传入时应该用中括号[ ]括起来。
  • channels:计算反向投影的通道列表,通道数必须与直方图维度相匹配。
  • hist:输入的模板图像直方图
  • ranges:直方图中每个维度bin的取值范围(即每个维度有多少个bin)
  • scale:可选输出反向投影的比例因子,一般取1。


importcv2ascv# 直方图反向投影defback_projection():
sample=cv.imread(r'./test/020.png')
target=cv.imread(r'./test/017.jpg')
# 转到HSV色彩空间roi_hsv=cv.cvtColor(sample, cv.COLOR_BGR2HSV)
target_hsv=cv.cvtColor(target, cv.COLOR_BGR2HSV)
# show imagecv.imshow('sample', sample)
cv.imshow('target', target)
# 调bins个数 少 效果更好  2D直方图roi_hist=cv.calcHist(images=[roi_hsv], channels=[0, 1], mask=None, histSize=[16, 16], ranges=[0, 180, 0, 256])
# 归一化到 0-255之间cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)
# 反向投影dst=cv.calcBackProject([target_hsv], [0, 1], roi_hist, [0, 180, 0, 256], 1)
cv.imshow('back_projection', dst)
back_projection()
cv.waitKey(0)
cv.destroyAllWindows()

运行效果如下:

opencv6.png




目录
相关文章
|
9月前
|
监控 数据可视化 数据挖掘
Python Rich库使用指南:打造更美观的命令行应用
Rich库是Python的终端美化利器,支持彩色文本、智能表格、动态进度条和语法高亮,大幅提升命令行应用的可视化效果与用户体验。
829 0
|
10月前
|
数据采集 监控 Java
Python 函数式编程的执行效率:实际应用中的权衡
Python 函数式编程的执行效率:实际应用中的权衡
403 102
|
9月前
|
机器学习/深度学习 算法 安全
【强化学习应用(八)】基于Q-learning的无人机物流路径规划研究(Python代码实现)
【强化学习应用(八)】基于Q-learning的无人机物流路径规划研究(Python代码实现)
665 6
|
9月前
|
设计模式 缓存 运维
Python装饰器实战场景解析:从原理到应用的10个经典案例
Python装饰器是函数式编程的精华,通过10个实战场景,从日志记录、权限验证到插件系统,全面解析其应用。掌握装饰器,让代码更优雅、灵活,提升开发效率。
607 0
|
10月前
|
数据采集 存储 数据可视化
Python网络爬虫在环境保护中的应用:污染源监测数据抓取与分析
在环保领域,数据是决策基础,但分散在多个平台,获取困难。Python网络爬虫技术灵活高效,可自动化抓取空气质量、水质、污染源等数据,实现多平台整合、实时更新、结构化存储与异常预警。本文详解爬虫实战应用,涵盖技术选型、代码实现、反爬策略与数据分析,助力环保数据高效利用。
511 0
|
10月前
|
存储 程序员 数据处理
Python列表基础操作全解析:从创建到灵活应用
本文深入浅出地讲解了Python列表的各类操作,从创建、增删改查到遍历与性能优化,内容详实且贴近实战,适合初学者快速掌握这一核心数据结构。
722 0
|
10月前
|
中间件 机器人 API
Python多态实战:从基础到高阶的“魔法”应用指南
Python多态机制通过“鸭子类型”实现灵活接口,使不同对象统一调用同一方法,自动执行各自行为。它简化代码逻辑、提升扩展性,适用于数据处理、策略切换、接口适配等场景。掌握多态思维,能有效减少冗余判断,使程序更优雅、易维护。
454 0
|
10月前
|
存储 监控 安全
Python剪贴板监控实战:clipboard-monitor库的深度解析与扩展应用
本文介绍了基于Python的剪贴板监控技术,结合clipboard-monitor库实现高效、安全的数据追踪。内容涵盖技术选型、核心功能开发、性能优化及实战应用,适用于安全审计、自动化办公等场景,助力提升数据管理效率与安全性。
326 0
|
11月前
|
存储 监控 安全
Python剪贴板监控实战:clipboard-monitor库的深度解析与扩展应用
本文介绍如何利用Python的clipboard-monitor库实现剪贴板监控系统,涵盖文本与图片的实时监听、防重复存储、GUI界面开发及数据加密等核心技术,适用于安全审计与自动化办公场景。
374 0
|
11月前
|
数据采集 API 调度
Python爬虫框架对比:Scrapy vs Requests在API调用中的应用
本文对比了 Python 中 Scrapy 与 Requests 两大爬虫框架在 API 调用中的差异,涵盖架构设计、调用模式、性能优化及适用场景,并提供实战建议,助力开发者根据项目需求选择合适工具。

推荐镜像

更多