OpenCV一些进阶操作

代码实现:

python 复制代码
import cv2
import numpy as np

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取灰度图像并转换为一维数组,用matplotlib绘制直方图
phone = cv2.imread('phone.png', cv2.IMREAD_GRAYSCALE)
a = phone.ravel()
plt.hist(a, bins=256)
plt.show()

# 使用cv2.calcHist计算直方图并绘制曲线
phone_hist = cv2.calcHist([phone], [0], None, [16], [0, 256])
plt.plot(phone_hist)
plt.show()

# 读取彩色图像,分别绘制B、G、R通道的直方图
img = cv2.imread('phone.png')
colors = ('b', 'g', 'r')
for i, col in enumerate(colors):
    histr = cv2.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(histr, color=col)
plt.show()

phone = cv2.imread('phone.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('phone',phone)
cv2.waitKey(0)
mask = np.zeros(phone.shape[:2],np.uint8)
mask[50:530,100:470] = 255
cv2.imshow('mask',mask)
cv2.waitKey(0)
Phone_mask = cv2.bitwise_and(phone,phone,mask=mask)
cv2.imshow('Phone_mask',Phone_mask)
cv2.waitKey(0)
Phone_hist_mask = cv2.calcHist([phone], [0], mask, [16], [0, 256])
plt.plot(Phone_hist_mask)
plt.show()



import matplotlib.pyplot as plt
import cv2
import numpy as np

# 读取灰度图像
woman = cv2.imread('black.jpg', cv2.IMREAD_GRAYSCALE)

# 绘制原始图像的直方图
plt.hist(woman.ravel(), bins=256)
plt.show()

# 全局直方图均衡化
woman_equalize = cv2.equalizeHist(woman)
# 绘制均衡化后图像的直方图
plt.hist(woman_equalize.ravel(), bins=256)
plt.show()

# 横向拼接原始图像与全局均衡化后的图像并显示
res = np.hstack((woman, woman_equalize))
cv2.imshow('woman_equalize', res)
cv2.waitKey(0)

# 创建自适应直方图均衡化对象
clahe = cv2.createCLAHE(clipLimit=1, tileGridSize=(16, 16))
# 应用自适应直方图均衡化
woman_clahe = clahe.apply(woman)

# 横向拼接原始、全局均衡化、自适应均衡化的图像并显示
res = np.hstack((woman, woman_equalize, woman_clahe))
cv2.imshow('phone_equalize', res)
cv2.waitKey(0)

代码是有关于图像直方图 的计算、绘制以及直方图均衡化(增强图像对比度)展开,使用了 OpenCV(cv2)进行图像处理,Matplotlib 进行可视化等操作。以下是分步骤解析:

一、基础库导入

代码开头重复导入了必要的库(实际开发中只需导入一次即可):

cv2:OpenCV 库,用于图像读取、处理

numpy:数值计算库,用于数组操作

matplotlib.pyplot:绘图库,用于绘制直方图和曲线

二、灰度图像直方图绘制

复制代码
# 读取灰度图像并转换为一维数组,用matplotlib绘制直方图
phone = cv2.imread('phone.png', cv2.IMREAD_GRAYSCALE)  # 以灰度模式读取图像
a = phone.ravel()  # 将二维图像数组展平为一维数组(便于直方图统计)
plt.hist(a, bins=256)  # 绘制直方图,bins=256表示将像素值(0-255)分为256个区间
plt.show()  # 显示直方图

功能:展示灰度图像的像素值分布。直方图的 x 轴是像素值(0-255,黑到白),y 轴是对应像素值的数量。

三、用 OpenCV 计算直方图并绘制

复制代码
# 使用cv2.calcHist计算直方图并绘制曲线
phone_hist = cv2.calcHist([phone], [0], None, [16], [0, 256])  # OpenCV计算直方图
plt.plot(phone_hist)  # 以曲线形式绘制直方图
plt.show()
  • cv2.calcHist参数解析:
    • [phone]:输入图像(需用列表包裹)
    • [0]:通道索引(灰度图只有 1 个通道,索引为 0)
    • None:掩膜(此处不使用掩膜,统计全图)
    • [16]:直方图的 bin 数量(将 0-255 分为 16 个区间,简化分布)
    • [0, 256]:像素值范围 功能 :用 OpenCV 的专用函数计算直方图,并用曲线展示(相比plt.hist更灵活,支持掩膜等高级功能)。

四、彩色图像的通道直方图

复制代码
# 读取彩色图像,分别绘制B、G、R通道的直方图
img = cv2.imread('phone.png')  # 读取彩色图像(OpenCV默认读取为BGR格式)
colors = ('b', 'g', 'r')  # 对应B、G、R通道的颜色
for i, col in enumerate(colors):
    histr = cv2.calcHist([img], [i], None, [256], [0, 256])  # 计算第i个通道的直方图
    plt.plot(histr, color=col)  # 用对应颜色绘制曲线
plt.show()

注意 :OpenCV 读取的彩色图是BGR格式(蓝、绿、红),而 Matplotlib 默认是RGB,但此处仅绘制直方图,颜色对应即可。

功能:分别展示彩色图像中蓝、绿、红三个通道的像素值分布,帮助分析图像的色彩构成。

五、掩膜(Mask)与感兴趣区域(ROI)的直方图

复制代码
phone = cv2.imread('phone.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('phone', phone)  # 显示原图
cv2.waitKey(0)  # 等待按键(0表示无限等待)

# 创建掩膜:黑色背景,特定区域为白色
mask = np.zeros(phone.shape[:2], np.uint8)  # 初始化与原图同大小的黑色掩膜(0为黑)
mask[50:530, 100:470] = 255  # 将区域[行50-530,列100-470]设为白色(255)
cv2.imshow('mask', mask)  # 显示掩膜
cv2.waitKey(0)

# 用掩膜提取原图中的感兴趣区域(ROI)
Phone_mask = cv2.bitwise_and(phone, phone, mask=mask)  # 只保留掩膜白色区域的像素
cv2.imshow('Phone_mask', Phone_mask)  # 显示ROI
cv2.waitKey(0)

# 计算掩膜区域的直方图
Phone_hist_mask = cv2.calcHist([phone], [0], mask, [16], [0, 256])  # mask参数指定只统计掩膜白色区域
plt.plot(Phone_hist_mask)
plt.show()

掩膜作用:过滤掉不感兴趣的区域,只分析特定区域的像素分布。

流程 :创建掩膜→用bitwise_and提取 ROI→计算 ROI 的直方图,适用于需要聚焦分析图像局部区域的场景。

六、直方图均衡化(增强对比度)

直方图均衡化通过拉伸像素值的分布范围,增强图像对比度(使暗部更暗、亮部更亮)。

1. 全局直方图均衡化
复制代码
# 读取灰度图像
woman = cv2.imread('black.jpg', cv2.IMREAD_GRAYSCALE)

# 绘制原始图像的直方图
plt.hist(woman.ravel(), bins=256)
plt.show()

# 全局直方图均衡化
woman_equalize = cv2.equalizeHist(woman)  # OpenCV内置全局均衡化函数
# 绘制均衡化后图像的直方图
plt.hist(woman_equalize.ravel(), bins=256)
plt.show()

# 横向拼接原始图像与全局均衡化后的图像并显示
res = np.hstack((woman, woman_equalize))  # 横向拼接两个图像
cv2.imshow('woman_equalize', res)
cv2.waitKey(0)

效果:全局均衡化会拉伸整个图像的像素分布,但可能过度增强噪声(尤其在均匀区域)。

2. 自适应直方图均衡化(CLAHE)

为解决全局均衡化的缺陷,自适应均衡化将图像分块(tile),对每块单独均衡化,同时限制对比度(避免噪声放大)。

复制代码
# 创建自适应直方图均衡化对象
clahe = cv2.createCLAHE(clipLimit=1, tileGridSize=(16, 16))  # clipLimit:对比度限制阈值;tileGridSize:分块大小(16x16)
# 应用自适应直方图均衡化
woman_clahe = clahe.apply(woman)

# 横向拼接原始、全局均衡化、自适应均衡化的图像并显示
res = np.hstack((woman, woman_equalize, woman_clahe))
cv2.imshow('phone_equalize', res)
cv2.waitKey(0)

优势:相比全局均衡化,自适应均衡化能更好地保留局部细节,避免整体过曝或噪声放大,是更常用的对比度增强方法。

总结

这段代码完整展示了图像直方图的计算、可视化(灰度图 / 彩色图 / ROI),以及通过直方图均衡化(全局 / 自适应)增强图像对比度的方法,是数字图像处理中分析和增强图像的基础技术实践。

相关推荐
NAGNIP5 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab6 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab6 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP10 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年10 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼10 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS10 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区11 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈11 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang12 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx