当前位置: 首页 > news >正文

计算机视觉(opencv)实战十六——图像像素直方图 与 掩膜


图像直方图与掩膜的应用

一、直方图的基本概念

直方图(Histogram)是图像处理中常用的一种工具,用于统计和展示图像中 像素值的分布情况
以灰度图为例,像素值范围为 0(黑色)到 255(白色),直方图的横坐标表示像素值,纵坐标表示该像素值出现的次数。

在 OpenCV 中,计算直方图的常用函数是:

cv2.calcHist(images, channels, mask, histSize, ranges)

参数说明:

  • images:输入图像,需要用中括号括起来,例如 [img]。支持 uint8float32 格式。

  • channels:通道索引。灰度图为 [0];彩色图像可以是 [0](蓝)、[1](绿)、[2](红)。

  • mask:掩膜图像。如果为 None,统计整张图像的直方图;如果传入掩膜,就只统计掩膜区域内的像素。

  • histSize:直方图的柱数(即 BIN 数)。例如 [256] 表示把像素值分成 256 个区间;[16] 表示分成 16 个区间。

  • ranges:像素取值范围,常用 [0, 256]

直方图可以帮助我们快速了解图像的整体亮度、对比度、以及色彩分布,是图像增强和分割的重要工具。

# cv2.calcHist(images,channels,mask,histSize,ranges) 计算图像的直方图,用于表示图像中像素灰度级的分布情况。
# images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]
# channels: 表示传入的图像通道数。如果输入图像是灰度图它的值就是 [0]。
#       如果是彩色图像 的传入的参数可以是 [0][1][2] 它们分别对应着 BGR。
# mask: 掩模图像。统计整副图像的直方图就把它为None。但是如果你想统计图像某一部分的直方图,你就制作一个掩模图像并使用它。
# histSize:BINS 的数目。也需用中括号括来 (分成多少个区间)
#   BINS :上面的直方图显示了每个像素值的像素数,即从0到255。即您需要256个值才能显示上述直方图。
#       但是请考虑一下,如果您不需要单独查找所有像素值的像素数,而是在像素值间隔内查找像素数,
#       该怎么办?例如,您需要找到介于 0 到 15 之间的像素数,然后是 16 到 31、32到47、...、240 到 255。
#       您只需要 16 个值来表示直方图。
# 因此,只需将整个直方图拆分为 16 个子部分,每个子部分的值就是其中所有像素计数的总和。
# 这每个子部分都称为"BIN"。在第一种情况下,条目数为256(每个像素一个),而在第二种情况下,它只有16。BINS 在 OpenCV 文档中由术语histSize表示。
# ranges: 像素值范围常为 [0 256]

二、使用 NumPy 和 Matplotlib 绘制直方图

下面的例子展示了如何用 NumPy 的 ravel() 将图像拉平成一维数组,并用 Matplotlib 绘制直方图:

import cv2
from matplotlib import pyplot as pltphone = cv2.imread('phone.png', cv2.IMREAD_GRAYSCALE)
a = phone.ravel()
plt.hist(a, bins=256)  
plt.show()
  • ravel():将多维数组展平成一维数组。

  • plt.hist():统计像素分布并绘制直方图。

结果是一幅灰度直方图,能直观反映出整幅图的灰度分布。


三、使用 OpenCV 计算直方图

相比 plt.hist,OpenCV 的 cv2.calcHist 提供了更灵活的统计方法:

phone_hist = cv2.calcHist([phone], [0], None, [256], [0,256])
plt.plot(phone_hist)
plt.show()

这里没有使用掩膜(mask=None),所以直方图统计了整张图像的像素。

在彩色图像中,可以分别计算三个通道的直方图:

img = cv2.imread('face.jpg')
color = ('b','g','r')
for i,col in enumerate(color):histr = cv2.calcHist([img], [i], None, [256], [0,256])plt.plot(histr, color=col)
plt.show()

这样绘制出的三条曲线分别表示蓝色、绿色和红色通道的像素分布。


四、掩膜(Mask)的概念与使用

在很多应用中,我们并不需要统计整幅图像的直方图,而是只关心某一部分区域。这时候就需要用到 掩膜(Mask)

掩膜是一幅 黑白图像(单通道,数值为 0 或 255):

  • 白色(255)区域表示要保留的部分。

  • 黑色(0)区域表示忽略的部分。

例如:

import cv2
import numpy as np
from matplotlib import pyplot as pltphone = cv2.imread('phone.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow('phone',phone)
cv2.waitKey(0)
mask = np.zeros(phone.shape[:2],np.uint8) 
mask[50:350,100:470] = 255
cv2.imshow('mask',mask)
cv2.waitKey(0)

这段代码生成了一张与原图大小相同的全黑图像,并在指定区域填充为白色,作为掩膜。

我们可以用 cv2.bitwise_and() 将掩膜应用到原图上,直观地看到选中的区域:

Phone_mask = cv2.bitwise_and(phone, phone, mask=mask)
cv2.imshow('phone_mask', Phone_mask)
cv2.waitKey(0)

五、带掩膜的直方图

cv2.calcHist 中传入掩膜参数,就能只统计掩膜范围内的像素分布:

phone_hist_mask = cv2.calcHist([phone], [0], mask, [256], [0,256])
plt.plot(phone_hist_mask)
plt.show()

这样绘制的直方图只反映掩膜区域的像素特征,而忽略其他部分。


六、应用场景

  • 图像增强:通过观察直方图分布,可以决定是否进行直方图均衡化来增强对比度。

  • 目标检测:使用掩膜提取特定区域的颜色直方图,作为目标特征进行匹配。

  • 图像分割:根据局部直方图判断区域的灰度或颜色特性,从而分割目标。


七、总结

  • 直方图:反映图像像素值的分布情况,是图像分析的基本工具。

  • 掩膜:用于限定直方图统计的区域,让我们能专注于关心的部分。

  • OpenCV 与 Matplotlib 提供了灵活的直方图绘制方式,既能全局统计,也能局部分析。

掌握直方图与掩膜,不仅能帮助理解图像的亮度和对比度,还能为后续的图像处理、特征提取和机器视觉任务打下基础。


文章转载自:

http://0XaehrmH.kjmcq.cn
http://0u6Xkiyf.kjmcq.cn
http://TBesweXI.kjmcq.cn
http://Gq2Z4LDR.kjmcq.cn
http://ibuDOu2V.kjmcq.cn
http://d8JjMF4I.kjmcq.cn
http://VOI5ByvV.kjmcq.cn
http://x0stOQ6c.kjmcq.cn
http://YFB69L4p.kjmcq.cn
http://GqE2dqsE.kjmcq.cn
http://40rCnJdl.kjmcq.cn
http://my546uss.kjmcq.cn
http://D7uMG7o6.kjmcq.cn
http://Qpw4yz1J.kjmcq.cn
http://GEXhgMmo.kjmcq.cn
http://XnDHsCoO.kjmcq.cn
http://phSF4BfD.kjmcq.cn
http://ajT0FpqD.kjmcq.cn
http://gmxPAcLW.kjmcq.cn
http://ONqsom99.kjmcq.cn
http://viTflGz7.kjmcq.cn
http://Dvq4xoh4.kjmcq.cn
http://EfzuekFH.kjmcq.cn
http://dEry2AuG.kjmcq.cn
http://KIAFPBGd.kjmcq.cn
http://ZnSss8pD.kjmcq.cn
http://iVhv2Tfb.kjmcq.cn
http://ZIXDvcPL.kjmcq.cn
http://JMg8SO1G.kjmcq.cn
http://7ipk3WhF.kjmcq.cn
http://www.dtcms.com/a/380304.html

相关文章:

  • SSH登录管理
  • 利用OpenCV进行指纹识别的案例
  • 知识点 | “比选”和“询价”
  • HarmonyOS多媒体开发:音视频播放与录制全解析
  • Linux文件IO——系统IO
  • Class51 深度循环神经网络
  • URLSearchParams
  • 使用 C# 设置 Excel 单元格格式
  • (二) Claude Code接入免费的Gemini-2.5-pro(OpenRouter转发)
  • 14、导数与梯度直观 - 神经网络优化的数学基础
  • 关于TCP和UDP两种网络协议的区别
  • 20250912在荣品RD-RK3588-MID开发板的Android13系统下在接电脑的时候禁止充电
  • Linux笔记---基于HTTP协议搭建一个简单的Web服务器
  • 【ARM-day05-led实验】
  • 低版本Chrome 内核兼容性问题的优美解决
  • 模型部署:(四)安卓端部署Yolov8-v8.2.99实例分割项目全流程记录
  • 使用自定义LLM和Embedding模型部署Vanna:基于RAG的Text-to-SQL生成
  • DataCollatorForCompletionOnlyLM解析(93)
  • 淘宝RecGPT:通过LLM增强推荐
  • Vue3 中使用 DOMPurify 对渲染动态 HTML 进行安全净化处理
  • 比较 iPhone:全面比较 iPhone 17 系列
  • 【Doris】集群介绍
  • 从“能写”到“能干活”:大模型工具调用(Function-Calling)的工程化落地指南
  • golang程序内存泄漏分析方法论
  • Go 语言 MQTT 消息队列学习指导文档
  • 基于数据挖掘技术构建电信5G客户预测模型的研究与应用
  • 【AI】pickle模块常见用途
  • 智慧园区,智启未来 —— 重塑高效、绿色、安全的产业新生态
  • MySQL 8新特性
  • 腾讯开源Youtu-GraphRAG