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




目录
相关文章
|
26天前
|
计算机视觉 开发者 Python
利用Python进行简单的图像处理
【10月更文挑战第36天】本文将引导读者理解如何使用Python编程语言和其强大的库,如PIL和OpenCV,进行图像处理。我们将从基本的图像操作开始,然后逐步深入到更复杂的技术,如滤波器和边缘检测。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供新的视角和技能,让你能够更好地理解和操作图像数据。
|
2月前
|
机器学习/深度学习 API 计算机视觉
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(下)
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(下)
31 2
|
2月前
|
机器学习/深度学习 存储 算法
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(上)
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(上)
40 1
|
2月前
|
计算机视觉 Python
python利用pyqt5和opencv打开电脑摄像头并进行拍照
本项目使用Python的PyQt5和OpenCV库实现了一个简单的摄像头应用。用户可以通过界面按钮打开或关闭摄像头,并实时预览视频流。点击“拍照”按钮可以捕捉当前画面并保存为图片文件。该应用适用于简单的图像采集和处理任务。
131 0
python利用pyqt5和opencv打开电脑摄像头并进行拍照
|
2月前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
80 2
|
2月前
|
算法 数据可视化 计算机视觉
Python中医学图像处理常用的库
在Python中,医学图像处理常用的库包括:ITK(及其简化版SimpleITK)、3D Slicer、Pydicom、Nibabel、MedPy、OpenCV、Pillow和Scikit-Image。这些库分别擅长图像分割、配准、处理DICOM和NIfTI格式文件、图像增强及基础图像处理等任务。选择合适的库需根据具体需求和项目要求。
78 0
|
2月前
|
数据挖掘 计算机视觉 Python
基于Python的简单图像处理技术
【10月更文挑战第4天】在数字时代,图像处理已成为不可或缺的技能。本文通过Python语言,介绍了图像处理的基本方法,包括图像读取、显示、编辑和保存。我们将一起探索如何使用PIL库进行图像操作,并通过实际代码示例加深理解。无论你是编程新手还是图像处理爱好者,这篇文章都将为你打开一扇新窗,让你看到编程与创意结合的无限可能。
|
4月前
|
计算机视觉 开发者 Python
使用Python进行简单图像处理
【8月更文挑战第31天】 本文将介绍如何使用Python编程语言来处理图像。我们将通过代码示例来展示如何读取、显示、编辑和保存图像文件。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供一个清晰的指引,帮助你开始自己的图像处理项目。
|
4月前
|
机器学习/深度学习 人工智能 监控
利用Python和OpenCV实现实时人脸识别系统
【8月更文挑战第31天】本文将引导您了解如何使用Python结合OpenCV库构建一个简易的实时人脸识别系统。通过分步讲解和示例代码,我们将探索如何从摄像头捕获视频流、进行人脸检测以及识别特定个体。本教程旨在为初学者提供一条明晰的学习路径,帮助他们快速入门并实践人脸识别技术。
|
2月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
472 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解