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




目录
相关文章
|
机器学习/深度学习 存储 数据挖掘
Python图像处理实用指南:PIL库的多样化应用
本文介绍Python中PIL库在图像处理中的多样化应用,涵盖裁剪、调整大小、旋转、模糊、锐化、亮度和对比度调整、翻转、压缩及添加滤镜等操作。通过具体代码示例,展示如何轻松实现这些功能,帮助读者掌握高效图像处理技术,适用于图片美化、数据分析及机器学习等领域。
489 20
|
8月前
|
人工智能 算法 计算机视觉
Python 图像处理技巧
本文介绍了Python图像处理中需要掌握的15个基本技能,涵盖图像读取与保存、颜色空间转换、裁剪与调整大小、滤波与平滑、边缘检测、阈值处理、形态学操作、直方图处理、特征检测与描述、图像配准与特征匹配、轮廓检测与分析、图像分割、模板匹配、透视变换与仿射变换以及傅里叶变换等内容。通过OpenCV、Pillow和Matplotlib等库实现相关功能,为图像处理提供了全面的基础指导。
240 0
|
9月前
|
机器学习/深度学习 算法 Java
OpenCV的理解及其应用
以上只是OpenCV的冰山一角,它的功能远不止这些。如果你对计算机视觉有兴趣,我强烈推荐你去尝试使用OpenCV,相信你会在使用过程中发现更多的有趣和实用的功能。
298 8
|
11月前
|
监控 Java 计算机视觉
Python图像处理中的内存泄漏问题:原因、检测与解决方案
在Python图像处理中,内存泄漏是常见问题,尤其在处理大图像时。本文探讨了内存泄漏的原因(如大图像数据、循环引用、外部库使用等),并介绍了检测工具(如memory_profiler、objgraph、tracemalloc)和解决方法(如显式释放资源、避免循环引用、选择良好内存管理的库)。通过具体代码示例,帮助开发者有效应对内存泄漏挑战。
582 1
|
XML 机器学习/深度学习 人工智能
使用 OpenCV 和 Python 轻松实现人脸检测
本文介绍如何使用OpenCV和Python实现人脸检测。首先,确保安装了OpenCV库并加载预训练的Haar特征模型。接着,通过读取图像或视频帧,将其转换为灰度图并使用`detectMultiScale`方法进行人脸检测。检测到的人脸用矩形框标出并显示。优化方法包括调整参数、多尺度检测及使用更先进模型。人脸检测是计算机视觉的基础技术,具有广泛应用前景。
581 10
|
机器学习/深度学习 算法 数据可视化
Python的计算机视觉与图像处理
本文介绍了Python在计算机视觉和图像处理领域的应用,涵盖核心概念、算法原理、最佳实践及应用场景。重点讲解了OpenCV、NumPy、Pillow和Matplotlib等工具的使用,并通过代码实例展示了图像读写、处理和可视化的方法。实际应用包括自动驾驶、人脸识别、物体检测等。未来趋势涉及深度学习、边缘计算和量子计算,同时也讨论了数据不足、模型解释性和计算资源等挑战。
635 2
|
计算机视觉 开发者 Python
利用Python进行简单的图像处理
【10月更文挑战第36天】本文将引导读者理解如何使用Python编程语言和其强大的库,如PIL和OpenCV,进行图像处理。我们将从基本的图像操作开始,然后逐步深入到更复杂的技术,如滤波器和边缘检测。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供新的视角和技能,让你能够更好地理解和操作图像数据。
|
机器学习/深度学习 API 计算机视觉
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(下)
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(下)
247 2
|
机器学习/深度学习 存储 算法
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(上)
基于Python_opencv人脸录入、识别系统(应用dlib机器学习库)(上)
384 1
|
计算机视觉 Python
python利用pyqt5和opencv打开电脑摄像头并进行拍照
本项目使用Python的PyQt5和OpenCV库实现了一个简单的摄像头应用。用户可以通过界面按钮打开或关闭摄像头,并实时预览视频流。点击“拍照”按钮可以捕捉当前画面并保存为图片文件。该应用适用于简单的图像采集和处理任务。
874 0
python利用pyqt5和opencv打开电脑摄像头并进行拍照

推荐镜像

更多