OpenCV 高阶实战:图像直方图与掩码图像深度解析

目录

一、图像直方图:读懂图像的 “像素分布报告”

1. 什么是图像直方图?

2. 图像直方图的核心作用

(1)分析亮度分布

(2)判断对比度高低

(3)辅助图像增强与阈值分割

(4)检测色彩偏移

3、举例

4. OpenCV 直方图计算:cv2.calcHist() 详解

(1)函数语法与参数解析

(2)实战案例:计算灰度图与彩色图直方图

(3)运行结果分析

二、掩码图像(Mask):精准定位感兴趣区域

1. 什么是掩码图像?

2. 掩码的核心应用场景

3. OpenCV 掩码操作:cv2.bitwise_and() 详解

(1)函数语法

(2)实战案例:用掩码提取局部区域并计算直方图

3)运行结果分析


在计算机视觉领域,图像直方图掩码图像是两种基础且核心的技术。直方图是分析图像像素分布的 “数据眼镜”,掩码则是精准定位感兴趣区域的 “手术刀”。本文将从概念原理出发,结合 OpenCV 实战代码,详细讲解图像直方图的计算与应用、掩码图像的制作与使用,以及直方图均衡化(含自适应均衡化)的实现,帮助大家掌握这两项 OpenCV 高阶技能。

一、图像直方图:读懂图像的 “像素分布报告”

1. 什么是图像直方图?

图像直方图是描述图像像素值分布的统计图形,它将图像的像素值(通常 0-255)作为横轴,像素值出现的频次(或概率)作为纵轴,用柱状图或折线图展示。

  • 对灰度图:直方图反映不同灰度级(0-255)的像素数量;
  • 对彩色图:可分别展示蓝(B)、绿(G)、红(R)三通道的像素分布。

简单来说,直方图就像图像的 “体检报告”,通过它能快速判断图像的亮度、对比度等关键信息。

2. 图像直方图的核心作用

(1)分析亮度分布
  • 若直方图峰值集中在左侧(低像素值):图像整体偏暗;
  • 若峰值集中在右侧(高像素值):图像整体偏亮;
  • 若峰值分布均匀:图像亮度适中。
(2)判断对比度高低
  • 直方图宽度宽(像素值跨度大,从 0 到 255 覆盖完整):对比度高,细节清晰;
  • 直方图宽度窄(像素值集中在某一区间):对比度低,图像灰蒙蒙。
(3)辅助图像增强与阈值分割
  • 直方图均衡化:通过重新分布像素值,扩大对比度;
  • 阈值分割:利用直方图的 “双峰谷底” 确定分割阈值,分离前景与背景(如分割文字与背景)。
(4)检测色彩偏移

对彩色图三通道直方图对比,若某一通道(如红色)峰值偏移明显,说明图像存在色彩偏色。

3、举例

灰度值在0 - 255范围之间总共 256 个值,可以将我们的范围划分为子部分(称为bins),例

4. OpenCV 直方图计算:cv2.calcHist() 详解

(1)函数语法与参数解析
cv2.calcHist(images, channels, mask, histSize, ranges, accumulate=False)

(2)实战案例:计算灰度图与彩色图直方图
import cv2
import matplotlib.pyplot as plt
import numpy as np# 1. 读取灰度图并计算直方图
# 读取灰度图像(以手机图像为例)
gray_img = cv2.imread("phone.png", cv2.IMREAD_GRAYSCALE)
if gray_img is None:print("图像读取失败,请检查文件路径!")exit()# 方法1:用matplotlib直接绘制(需将图像展平为一维数组)
plt.figure(figsize=(12, 5))
plt.subplot(1, 3, 1)
plt.hist(gray_img.ravel(), bins=256, color='gray')  # ravel()将二维图像转为一维
plt.title("灰度图直方图(matplotlib)")
plt.xlabel("像素值(0-255)")
plt.ylabel("像素数量")# 方法2:用OpenCV的cv2.calcHist()计算(bins=16,分组更粗)
hist_cv2 = cv2.calcHist([gray_img], [0], None, [16], [0, 256])
plt.subplot(1, 3, 2)
plt.plot(hist_cv2, color='black', marker='o')  # 折线图展示
plt.title("灰度图直方图(cv2.calcHist,bins=16)")
plt.xlabel("分组索引(0-15)")
plt.ylabel("像素数量")# 2. 读取彩色图并计算三通道直方图
color_img = cv2.imread("phone.png")  # OpenCV默认BGR格式
color = ('b', 'g', 'r')  # 对应B/G/R通道plt.subplot(1, 3, 3)
for i, col in enumerate(color):# 分别计算B、G、R通道的直方图hist_channel = cv2.calcHist([color_img], [i], None, [256], [0, 256])plt.plot(hist_channel, color=col, label=f"{col.upper()}通道")plt.title("彩色图三通道直方图")
plt.xlabel("像素值(0-255)")
plt.ylabel("像素数量")
plt.legend()
plt.tight_layout()
plt.show()# 展示原始图像
cv2.imshow("灰度图", gray_img)
cv2.imshow("彩色图(BGR)", color_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

(3)运行结果分析
  • 灰度图直方图:可直观看到图像像素集中在哪个区间(如集中在 100-200,说明图像偏亮);
  • 彩色图三通道:若 B 通道峰值高于 G/R,说明图像偏蓝;反之则偏红或偏绿;
  • bins=16 时,直方图更简洁,适合快速观察整体分布趋势。

二、掩码图像(Mask):精准定位感兴趣区域

1. 什么是掩码图像?

掩码图像是与原图像尺寸完全相同的二进制图像,像素值仅为 0 或 255(无符号 8 位整数,np.uint8):

  • 像素值为 0屏蔽区域(后续操作不处理该区域);
  • 像素值为 255保留区域(后续操作仅作用于该区域)。

形象地说,掩码就像 “照片遮罩”,只让感兴趣的区域 “透出来” 参与处理。

2. 掩码的核心应用场景

  • 计算局部区域的直方图(如仅分析人脸区域的亮度);
  • 图像修复(如仅修复口罩遮挡的面部区域);
  • 目标分割(如仅提取图像中的文字区域);
  • 图像融合(如将 logo 贴到指定区域)。

3. OpenCV 掩码操作:cv2.bitwise_and() 详解

掩码通常与按位与运算结合使用,原理是:原图像像素 & 掩码像素,只有当掩码像素为 255(二进制 11111111)时,原像素值才保留;若掩码为 0(二进制 00000000),结果为 0(黑色)。

(1)函数语法
cv2.bitwise_and(src1, src2, dst=None, mask=None)

(2)实战案例:用掩码提取局部区域并计算直方图
import cv2
import numpy as np
import matplotlib.pyplot as plt# 1. 读取灰度图像
gray_img = cv2.imread("phone.png", cv2.IMREAD_GRAYSCALE)
cv2.imshow("原始灰度图", gray_img)
cv2.waitKey(0)# 2. 创建掩码图像(步骤:全0矩阵 → 局部设为255)
# 2.1 生成与原图像尺寸相同的全0矩阵(纯黑图像)
mask = np.zeros(gray_img.shape[:2], dtype=np.uint8)  # shape[:2]取高和宽
# 2.2 定义感兴趣区域(ROI):[y1:y2, x1:x2](注意:OpenCV中坐标是(y, x))
# 此处以“手机屏幕区域”为例,需根据实际图像调整坐标
mask[50:350, 100:470] = 255  # 该区域设为255(白色)# 展示掩码图像
cv2.imshow("掩码图像(白色为保留区域)", mask)
cv2.waitKey(0)# 3. 应用掩码:提取感兴趣区域
masked_img = cv2.bitwise_and(gray_img, gray_img, mask=mask)
cv2.imshow("掩码提取后的图像", masked_img)
cv2.waitKey(0)# 4. 对比:全图直方图 vs 掩码区域直方图
plt.figure(figsize=(10, 4))# 全图直方图
plt.subplot(1, 2, 1)
hist_full = cv2.calcHist([gray_img], [0], None, [256], [0, 256])
plt.plot(hist_full, color='black')
plt.title("全图直方图")
plt.xlabel("像素值")
plt.ylabel("数量")# 掩码区域直方图
plt.subplot(1, 2, 2)
hist_masked = cv2.calcHist([gray_img], [0], mask, [256], [0, 256])
plt.plot(hist_masked, color='red')
plt.title("掩码区域(手机屏幕)直方图")
plt.xlabel("像素值")
plt.ylabel("数量")plt.tight_layout()
plt.show()cv2.destroyAllWindows()

运行结果如下:

3)运行结果分析
  • 掩码图像:黑色区域为屏蔽区,白色矩形为保留的 “手机屏幕区域”;
  • 掩码提取后的图像:仅屏幕区域保留原像素,其他区域为黑色;
  • 直方图对比:若屏幕区域偏亮,掩码直方图峰值会比全图直方图更靠右,精准反映局部亮度分布。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922000.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于stm32的家庭安全监测系统设计

若该文为原创文章,转载请注明原文出处。一、引言(一)研究背景及意义背景:随着智能家居概念的普及,人们对家庭安全、舒适度和节能提出了更高要求。传统安防系统功能单一、各系统独立,缺乏联动和远程管理能力…

Oracle体系结构-控制文件(Control Files)

一、 原理 (Principle) 核心定位: 控制文件是一个小型的二进制文件,由 Oracle 实例在启动和操作过程中持续读写。它是数据库物理结构的权威记录。数据库无法启动或正常操作时,如果无法访问控制文件,实例将无法识别数据文件和重做日…

路由 下一跳 网关 两个不同网段的ip如何通过路由器互通

路由 (Routing)核心思想:路径选择是什么? 路由是指数据包从源主机传输到目标主机的整个过程。这个过程就像寄快递:你需要决定包裹经过哪些中转站才能最终到达收件人手里。做什么? 网络中的设备(主要是路由器&#xff0…

HiDDeN论文解读与代码实现

论文:HiDDeN: Hiding Data With Deep Networks 作者:Jiren Zhu, Russell Kaplan, Justin Johnson, Li Fei-Fei一、研究背景 在图像信息隐藏领域,通常有两类典型的应用场景:隐写 (Steganography) 目标:实现秘密通信。要…

实验室服务器配置|实验室多人共享GPU|通过Docker实现Linux系统多用户隔离与安全防控

利用实验室服务器跑实验的时候,通常就是两种方案,一个是向日葵远程桌面进行操作,一个是通过ssh进行连接,用ssh的话,一般服务器都在内网(例如校园网),是无法在公网(不在校…

2019考研数学(二)真题

一、选择题 (1) (2) (3) (4) 遗漏点:由通解知特解,特解代入微分方程 (5) ★记住这个题,用的泰勒展开(6) (7) 遗忘点: ★伴随矩阵的秩与原矩阵秩的关系: (8) 错误点:粗心 二、填空题 (9) 易混淆点&#xff…

10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑之旅

10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑笔记 如果你也曾 复制了官方 Demo 却不知道怎么拆、窗口一拉伸图表就变形、切换标签页后内存暴涨——这篇博客就是为你写的。 我会用 6 个递进版本 的源码,带你把一张 最简柱状图 逐步进化成 可销毁…

二级缓存在实际项目中的应用

二级缓存在项目中的应用 目录 1. 二级缓存简介2. 应用场景3. 重难点分析4. 结合SpringBoot使用5. 最佳实践与案例6. 总结 1. 二级缓存简介 1.1 什么是二级缓存 二级缓存(Second-Level Cache) 是Hibernate框架中的一个重要特性,它提供了应…

深入浅出CRC校验:从数学原理到单周期硬件实现 (2)CRC数学多项式基础

数学的优雅:剖开CRC的多项式除法核心看似复杂的CRC校验,其核心建立在优雅的数学基础之上。本文将为您揭开CRC算法的数学面纱,让您真正理解多项式除法的精妙之处。模2运算:CRC世界的特殊算术 CRC计算建立在一种特殊的代数系统上——…

软考初级有没有必要考?

对正在学习相关专业的学生或者是行业新人,这篇文章从软考初级的含义、适合哪些人考、考试难度等方面解答,帮助你判断要不要报考。一、软考初级是什么? 软考初级是软考体系里面的基础级别,主要面向在校大学生或是IT行业新人&#x…

11 Prompt 工程进阶:Few-shot 与 Chain-of-Thought

11 Prompt 工程进阶:Few-shot 与 Chain-of-Thought 前10节总结 & 后10节展望 在前 10 节,我们已经完成了 AI 产品经理的入门阶段: 1–3:理解了大模型的基本概念、Token、Prompt 基础;4–5:体验了本地部…

ARM1.(ARM体系结构)

1.基本概念嵌入式:以应用为心,以计算机技术为础,软便件可被的专用计算机系统。计算机系统的软件基本组成: 系统软件、应用软件。计算机系统的硬件基本组成:运算器、控制器、存诸器、输入设备、输出设备日常生活中遇到的专业术语&#xff1a…

Django全栈班v1.01 Python简介与特点 20250910

从零开始的Python编程之旅 “人生苦短,我用Python。”这不仅仅是Python程序员的口头禅,更是对Python强大能力的最好诠释!!! 为什么全世界有超过1500万开发者选择Python? 为什么Python连续多年蝉联最受欢…

【WebApi】什么情况开启如何开启缓存

在 ASP.NET Core WebAPI 中开启缓存是优化性能、减少服务器负载和提升用户体验的非常重要的手段。但并非所有情况都适合开启缓存。 下面我将从 “什么情况下开启” 和 “如何开启” 两个方面为你详细解释。 一、什么情况下应该开启缓存? 总的来说,缓存适用于 “变化不频繁但…

Go语言类型断言全解析

类型断言的基本概念类型断言(Type Assertion)是Go语言中用于检查接口值底层具体类型的机制。它本质上是一种运行时类型检查的操作,允许程序在运行时判断接口变量是否持有特定的类型值,并提取该类型的值。这是Go语言类型系统中的一个重要特性,…

大模型在题目生成中的安全研究:攻击方法与防御机制

大模型在题目生成中的安全研究:攻击方法与防御机制 文章目录大模型在题目生成中的安全研究:攻击方法与防御机制一、引言二、大模型在题目生成中的安全漏洞与攻击方法2.1 大模型在题目生成中的安全漏洞分析2.1.1 训练数据相关漏洞2.1.2 模型架构与特性相关…

跟做springboot尚品甄选项目(二)

登录功能的书写 后端接口的书写 (1)创建配置文件 粘贴这两个文件(E:\project\AllProJect\Shangpin Selection\项目材料素材\资料\资料\03-配置文件) 在spzx-manager服务的src/resources目录下创建application.yml、application-…

前后端接口调试提效:Postman + Mock Server 的工作流

前后端接口调试提效:Postman Mock Server 的工作流 🌟 Hello,我是摘星! 🌈 在彩虹般绚烂的技术栈中,我是那个永不停歇的色彩收集者。 🦋 每一个优化都是我培育的花朵,每一个特性都是…

大带宽香港云服务器在数据传输速度上有何优势?

为方便站长快速部署网站、优化用户访问体验,当下众多实力强劲的香港数据中心,均推出了大带宽云服务器产品。不过,市面上不少数据中心虽宣称提供 “专属大带宽”,但其线路配置中,国际线路占比高、绕行链路多&#xff0c…

HT862 智能音频功率放大器:为便携音频设备打造高效稳定的音质解决方案

在蓝牙音箱、智能手机、便携式游戏机等设备的设计中,音频功率放大器是决定音质表现、续航能力与使用稳定性的关键部件。一款优质的音频功放,不仅需要输出足够的功率以满足清晰响亮的听觉需求,还需在能效、温控、适配性上达到平衡,…