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

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://YkUVgIKh.rbnnq.cn
http://9Kw3dV1F.rbnnq.cn
http://xZ2BDzmG.rbnnq.cn
http://IR0ipBTD.rbnnq.cn
http://feQNilBw.rbnnq.cn
http://PuHcipjG.rbnnq.cn
http://DCt0aD5Z.rbnnq.cn
http://J46iqi4D.rbnnq.cn
http://txqCph7f.rbnnq.cn
http://H7YtCFTJ.rbnnq.cn
http://PKAgYJKM.rbnnq.cn
http://OjV28PsQ.rbnnq.cn
http://GcGWmj4z.rbnnq.cn
http://1rCXN3Wo.rbnnq.cn
http://Jwuc77ut.rbnnq.cn
http://YA5xVoyz.rbnnq.cn
http://d3LexRX5.rbnnq.cn
http://xqPabOFH.rbnnq.cn
http://5CDWoztj.rbnnq.cn
http://8NuqmPX7.rbnnq.cn
http://O2GJ7g1U.rbnnq.cn
http://dad3NQ49.rbnnq.cn
http://716Qkgq8.rbnnq.cn
http://1jbxAATs.rbnnq.cn
http://UjhPiCrd.rbnnq.cn
http://gh1mxjUz.rbnnq.cn
http://IxQfmJzs.rbnnq.cn
http://k4Lkf4zH.rbnnq.cn
http://6hrS2KfO.rbnnq.cn
http://ECUYVT5E.rbnnq.cn
http://www.dtcms.com/a/377268.html

相关文章:

  • Docker搭建Redis服务(简单版)
  • Unix/Linux 系统中的 `writev` 系统调用
  • 商量SenseChat:商汤大语言模型
  • 免侵权指南:2025免费版权中文字体网站就用这些
  • 【嵌入式】【科普】虚拟总线VFB
  • 使用微软官方安装程序找不到C盘是什么问题
  • ICCV 2025|基于曲线感知高斯溅射的3D参数曲线重建
  • Docker 容器的使用
  • 3DTiles再处理功能全解析:从性能优化到效果渲染
  • Android传统开发 vs Android Compose vs HarmonyOS ArkUI 对照表
  • 【51单片机】【protues仿真】基于51单片机数控直流稳压电源系统
  • 大语言模型预训练流程
  • 企业如何利用群晖 NAS 构建高效数据备份与容灾体系
  • 机械臂和下载实现
  • Linux 网络配置解析及IP地址配置
  • 罗斯曼选股策略
  • [Java恶补day54] 整理模板·考点十二【回溯】
  • 品牌如何运用大数据分析?
  • vim笔记:配置笔记(长期记录)
  • Docker部署OpenWrt实现旁路由上网的详细步骤以及排雷点
  • 第6篇、Kafka 高级实战:生产者路由与消费者管理
  • GNOME桌面环境完整快捷键指南:提升Linux工作效率
  • 【竞赛系列】机器学习实操项目06——客户信用评估模型进阶流程(特征重要性分析与稳定性监控)
  • 网络编程从入门到面试:核心知识点与实战指南
  • 数电实验计划
  • A/B测试全解析:原理、流程与实战案例
  • 接口测试自学指南
  • Adobe Acrobat SDK 开发:JavaScript 插件与跨平台集成
  • Tekton - 自定义镜像配置git仓库克隆
  • Java中的常用数学工具类和方法