使用Python,OpenCV计算图像直方图(cv2.calcHist)
使用Python,OpenCV计算图像直方图(cv2.calcHist
- 1. 效果图
- 2. 原理
- 2.1 什么是图像直方图?
- 2.2 计算直方图
- 2.3 可视化蒙版区域
- 3. 源码
- 参考
这篇博客将介绍如何使用Python,OpenCV和cv2.calcHist 计算图像直方图。
直方图算机视觉中应用广泛。
- 使用灰度直方图进行阈值处理;
- 使用直方图进行白平衡;
- 使用颜色直方图来跟踪图像中的对象,例如使用 CamShift 算法;
- 使用颜色直方图作为特征——包括多维的颜色直方图;
- 使用图像梯度的直方图来形成 HOG 和 SIFT 描述符;
- 在图像搜索引擎和机器学习中使用的极受欢迎的视觉词袋表示也是直方图!
而且很有可能,我敢肯定这不是您第一次在研究中遇到直方图。
为什么直方图如此有用?
因为直方图捕获了一组数据的频率分布。事实证明,检查这些频率分布是构建简单图像处理技术……以及非常强大的机器学习算法的一种非常好的方式。
1. 效果图
原图BGR图:
颜色不对,因为OpenCV读取图片默认Numpy是BGR通道形式,而matplotlib期待RGB通道的图像,所以先转换在展示~
原图RGB图 VS 灰度图效果如下:
灰度图 VS 灰度直方图 VS 归一化灰度直方图效果图如下:
归一化的意义可以保证:同一图像等比例缩放后,归一化直方图也相同。
从直方图中可以看出:落在(0~30)像素范围的像素较多,说明图像中包含有“黑色”像素。
BGR-扁平化的彩色直方图如下:
2维3种组合的效果图如下:,从图中可以看到 G and R的峰值更多一些~,查看原始图确实红色和绿色更多一些。
原图 VS 蒙版区域效果图如下:
蒙版区域直方图如下,可以看到绿色、红色像素峰值多一些
2. 原理
2.1 什么是图像直方图?
直方图表示图像中像素强度(无论是彩色还是灰度)的分布。它可以被可视化为一个图形,给出了强度(像素值)分布的高级直觉。
假设一个 RGB 颜色空间,所有像素值将在 0 到 255 的范围内。在绘制直方图时,x 轴充当“bins”。如果用 256 构建一个直方图
bins,然后有效地计算每个像素值出现的次数。
相反,如果只使用 2(等距)bins,然后计算像素在 [0, 128] 或 [128, 255] 范围内的次数。然后将合并到 x 轴值的像素数绘制在 y 轴上。
通过简单地检查图像的直方图,可以大致了解对比度、亮度和强度分布。
2.2 计算直方图
cv2.calcHist(images, channels, mask, histSize, ranges)
- images 要计算直方图的原始图像
- channels 通道,[0]:灰度直方图,[0,1,2]BGR彩色直方图
- mask 要为某个蒙版像素计算直方图,没有可设置为None
- histSize x轴要分的bins个数[32,32,32],每个通道分为32个区间
- range 可能的像素范围[0,256] 因为calHist不包含后者
2.3 可视化蒙版区域
- 构建和原图相同的黑色像素图
- 绘制一个矩形白色
- 原图与蒙版图使用按位与来可视化图像的蒙版区域
3. 源码
# 为单通道灰度图计算直方图
# USAGE
# python all_histogram.py# 导入必要的包
from matplotlib import pyplot as plt
import argparse
import cv2
import numpy as npdef plot_histogram(image, title, mask=None):# 拆分图像为BGR通道,初始化每个通道的名称chans = cv2.split(image)colors = ("b", "g", "r")plt.figure()plt.title(title)plt.xlabel("Bins")plt.ylabel("# of Pixels")# 遍历图像通道for (chan, color) in zip(chans, colors):# 为当前通道计算直方图,并展示hist = cv2.calcHist([chan], [0], mask, [256], [0, 256])plt.plot(hist, color=color)plt.xlim([0, 256])# 构建命令行参数及解析
# --image 输入图像
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=False, default="ml4.jpg",help="path to the image")
args = vars(ap.parse_args())# 加载图像,并转换灰度图
image = cv2.imread(args["image"])
plt.figure()
plt.title("BGR Origin Image")
plt.axis("off")
plt.imshow(image)plt.figure()
plt.title("RGB Origin Image")
plt.axis("off")
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 计算灰度直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])# 计算图像直方图后,在屏幕上显示灰度图像并绘制未归一化的图像直方图
# Numpy读取图片后以BGR通道形式,matplotlib期待RGB通道的图像,所以先转换在展示~
plt.figure()
plt.title("Gray Origin Image")
plt.axis("off")
plt.imshow(cv2.cvtColor(image, cv2.COLOR_GRAY2RGB))# 非标准化直方图计算分布的原始频率。考虑计算一个包中不同颜色的 M&M 的数量,最终可得到每种颜色的整数计数,/总数得到比率。
# 归一化比率可以很方便的解决同一个图像只是尺寸等比例缩放但直方图差距很大的问题。
# 绘制直方图
plt.figure()
plt.title("Grayscale Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")
plt.plot(hist)
plt.xlim([0, 256])# 归一化直方图
hist /= hist.sum()# 展示归一化的直方图
plt.figure()
plt.title("Grayscale Histogram (Normalized)")
plt.xlabel("Bins")
plt.ylabel("% of Pixels")
plt.plot(hist)
plt.xlim([0, 256])
plt.show()# 分离图像的3通道 初始化通道名
image = cv2.imread(args["image"])
chans = cv2.split(image)
colors = ("b", "g", "r") # 初始化通道名称
# 初始化matplotlib图
plt.figure()
plt.title("'Flattened' Color Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")# 遍历图像通道
for (chan, color) in zip(chans, colors):# 为当前通道绘制直方图,并展示hist = cv2.calcHist([chan], [0], None, [256], [0, 256])# hist /= hist.sum()plt.plot(hist, color=color)plt.xlim([0, 256])# 加载图像并绘制直方图
image = cv2.imread("ml0.jpg")
plot_histogram(image, "Histogram for Original Image")# 为图像构建一个mask,蒙版将是黑色像素忽略,只关注白色像素
mask = np.zeros(image.shape[:2], dtype="uint8")
cv2.rectangle(mask, (260, 290), (490, 520), 255, -1)# 展示蒙版区域
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Applying the Mask", masked)# 为蒙版图像计算直方图,并展示(在直方图计算中只考虑原始图像中属于掩码区域的像素。)
plot_histogram(image, "Histogram for Masked Image", mask=mask)# 展示结果
plt.show()
参考
- https://www.pyimagesearch.com/2021/04/28/opencv-image-histograms-cv2-calchist/
使用Python,OpenCV计算图像直方图(cv2.calcHist)相关推荐
- 【Python OpenCV】图像直方图 calcHist方法 equalizeHist方法
[Python OpenCV]图像直方图 calcHist方法 equalizeHist方法 (一)图像直方图 图像的构成是有像素点构成的,每个像素点的值代表着该点的颜色(灰度图或者彩色图).所谓直方 ...
- C++ opencv之图像直方图(calcHist)
这篇博客我们主要来学习图像直方图. 图像直方图是图像像素值的统计学特征.计算代价较小,具有图像平移.旋转.缩放不变性等众多优点,广泛地应用于图像处理的各个领域,特别是灰度图像的阈值分割.基于颜色的图像 ...
- python图片相似度计算_python Opencv计算图像相似度过程解析
这篇文章主要介绍了python Opencv计算图像相似度过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.相关概念 一般我们人区分谁是谁 ...
- VS+openCV 用直方图统计像素(上)计算图像直方图、利用查找表修改图像外观
一.计算图像直方图 图像由各种数值的像素构成.例如在单通道灰度图像中,每个像素都有一个 0(黑色)~255(白色)的整数.对于每个灰度,都有不同数量的像素分布在图像内,具体取决于图片内容. 直方图是一 ...
- Python+OpenCV:图像对比度受限自适应直方图均衡化(CLAHE, Contrast Limited Adaptive Histogram Equalization)
Python+OpenCV:图像对比度受限自适应直方图均衡化(CLAHE, Contrast Limited Adaptive Histogram Equalization) ############ ...
- Python OpenCV 图像处理之直方图的应用,取经之旅第 26 天
Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧. Python OpenCV 基础知识铺垫 cv2.compareHist 函数 橡皮擦的小节 基础知识铺垫 上篇博客 Py ...
- Python+OpenCV:图像轮廓
Python+OpenCV:图像轮廓 轮廓是什么? 轮廓可以简单地解释为一条连接所有连续点(沿边界)的曲线,具有相同的颜色和强度. 轮廓线是形状分析.目标检测和识别的重要工具. 为了获得更好的精度,可 ...
- Python+OpenCV:图像梯度
Python+OpenCV:图像梯度(Image Gradients) 理论 OpenCV提供了三种类型的梯度滤波器或高通滤波器,Sobel, Scharr和Laplacian. 1. Sobel和S ...
- Python+OpenCV判断图像是黑底还是白底
前言 本篇博客使用Python+OpenCV判断图像是黑底还是白底,利用图像对角线上的黑白像素点个数进行判断,详情见下文. 本篇博客内容包含代码逻辑.说明.依赖.实现,这几部分.代码实现部分包含2种实 ...
最新文章
- Greenplum 2000亿 近似度查询 性能 以及注意事项
- 小菜的 VUE 使用技巧 持续更新
- ASP.NET之纠错
- 博图wincc连接数据块_西门子博途WINCC 可通过创建画面模板提高编程效率
- VTK:vtkCursor3D用法实战
- 结合提供者模式解析Jenkins源码国际化的实现
- 新能源汽车简史——电动汽车沉浮录
- 2019年Java开发者进阶手册.pdf
- Windows Phone开发(18):变形金刚第九季——变换 转:http://blog.csdn.net/tcjiaan/article/details/7385056...
- mysql 报错5 拒绝访问_linux上装mysql
- 如何断点调试Tomcat源码
- bat操作ftp上传下载命令
- PHPUnit简介及使用
- modern android5.1,Modern摩登印app下载-Modern摩登印安卓版下载 v1.1.5_5577安卓网
- html中em使用例子,HTML DOM Emphasized用法及代码示例
- 使用trash-cli给Linux服务器加一个回收站的功能
- ACW829模拟队列
- class函数 python_python中class函数如何使用
- kafka topic 操作
- 计算机毕业设计 SSM超市收银管理系统 便利店收银管理系统 酒吧收银管理系统 酒店收银系统Java Vue MySQL数据库 远程调试 代码讲解