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),以及通过直方图均衡化(全局 / 自适应)增强图像对比度的方法,是数字图像处理中分析和增强图像的基础技术实践。

相关推荐
新智元2 小时前
起猛了!这个国家任命 AI 为「部长」:全球首个,手握实权,招标 100% 透明
人工智能·openai
张较瘦_2 小时前
[论文阅读] 人工智能 + 软件工程 | 大语言模型驱动的多来源漏洞影响库识别研究解析
论文阅读·人工智能·语言模型
艾醒2 小时前
大模型面试题剖析:RAG中的文本分割策略
人工智能·算法
算家计算2 小时前
马斯克突然裁掉500名AI训练师!重心转向招募专业领域AI导师
人工智能·资讯·grok
什么都想学的阿超2 小时前
【大语言模型 58】分布式文件系统:训练数据高效存储
人工智能·语言模型·自然语言处理
ViperL12 小时前
[智能算法]可微的神经网络搜索算法-FBNet
人工智能·深度学习·神经网络
新智元2 小时前
马斯克深夜挥刀,Grok 幕后员工 1/3 失业!谷歌 AI 靠人肉堆起,血汗工厂曝光
人工智能·openai
带娃的IT创业者2 小时前
Windows 平台上基于 MCP 构建“文心一言+彩云天气”服务实战
人工智能·windows·文心一言·mcp