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

相关推荐
大龄程序员狗哥7 小时前
第47篇:使用Speech-to-Text API快速构建语音应用(操作教程)
人工智能
KKKlucifer7 小时前
数据安全合规自动化:策略落地、审计追溯与风险闭环技术解析
人工智能·安全
RWKV元始智能7 小时前
RWKV超并发项目教程,RWKV-LM训练提速40%
人工智能·rnn·深度学习·自然语言处理·开源
dyj0957 小时前
Dify - (一)、本地部署Dify+聊天助手/Agent
人工智能·docker·容器
墨染天姬8 小时前
【AI】Hermes的GEPA算法
人工智能·算法
小超同学你好8 小时前
OpenClaw 深度解析系列 · 第8篇:Learning & Adaptation(学习与自适应)
人工智能·语言模型·chatgpt
紫微AI8 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
码途漫谈8 小时前
Easy-Vibe开发篇阅读笔记(四)——前端开发之结合 Agent Skills 美化界面
人工智能·笔记·ai·开源·ai编程
易连EDI—EasyLink8 小时前
易连EDI–EasyLink实现OCR智能数据采集
网络·人工智能·安全·汽车·ocr·edi
冬奇Lab8 小时前
RAG 系列(二):用 LangChain 搭建你的第一个 RAG Pipeline
人工智能·langchain·llm