OpenCV一些进阶操作
代码实现:
import cv2
import numpy as npimport 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),以及通过直方图均衡化(全局 / 自适应)增强图像对比度的方法,是数字图像处理中分析和增强图像的基础技术实践。