opencv:直方图

前言

直方图是机器视觉中用于分析图像灰度或颜色分布的重要工具。

基本概念

  • 定义:直方图描述图像中各灰度级像素出现的频率,横轴为灰度级(0-255),纵轴为对应灰度级的像素数量。
  • 性质
    • 反映图像的灰度分布规律,但不包含像素位置信息。
    • 每幅图像有唯一的直方图,但不同图像可能有相同直方图。
    • 若图像由不相连区域组成,总直方图为各区域直方图之和。

应用

  • 图像质量评估:通过直方图分布判断图像亮度和对比度。
  • 阈值选择:在图像分割中,根据直方图峰谷确定二值化阈值。
  • 直方图均衡化:增强图像对比度,使灰度分布更均匀

计算直方图

cv2.calcHist(images,channels,mask,histSize,ranges)

  • images:原图像图像格式为uint8或float32。当传入函数时应用中括号[]括起来例如[img]

  • channels:同样用中括号括起来,它会告函数我们统幅图像的直方图。如果入图像是灰度图它的值就是[0]如果是彩色图像的传入的参数可以是[0][1][2]它们分别对应着BGR。

  • mask:掩码图像。统整幅图像的直方图就把它为None。但是如果你想统图像某一分的直方图的你就制作一个掩码图像并使用它。

  • histSize:BIN 的数目。也应用中括号括起来

  • ranges:像素值范围通常为[0, 256]

    这是个灰度图

    img = cv2.imread("img1.jpg",cv2.IMREAD_GRAYSCALE)

    直方图计算

    hist = cv2.calcHist([img],[0],None,[256],[0,256])

    绘制直方图显示

    plt.hist(img.ravel(),256)
    plt.show()

显示RGB三色的直方图:

复制代码
img = cv2.imread("img1.jpg")
color = ('b', 'g', 'r')
for i, col in enumerate(color):
    histr = cv2.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(histr, color=col)
    plt.xlim([0, 256])

mask操作

掩码操作就是创建一个黑白二值图像,这个二值图像与你想要进行掩码操作的图像大小一致,然后将二值图像与原图像结合,二值图像中白色像素对应的原图像像素点保留,黑色像素对应的原图像像素点变为黑色,从而达到只对部分像素点进行操作的效果。

准确来说,掩码操作就像是做手术前给病人盖上一张手术洞巾,只对洞里的部分进行操作。

复制代码
img = cv2.imread("img1.jpg", cv2.IMREAD_COLOR)
# 创建mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255    # 将想要处理的部分设置为白色

cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
复制代码
img = cv2.imread("img1.jpg", cv2.IMREAD_COLOR)
# 创建mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255  # 将想要处理的部分设置为白色
# 图像进行'与'操作,打上掩码
masked_img = cv2.bitwise_and(img, img, mask=mask)

cv2.imshow("masked_img", masked_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

直方图均匀化

均匀化效果如上图所示,直方图均匀化是为了提升图像的色彩与亮度。

直方图均匀化,从第二张图可以看出,具体的操作就是从每个像素点之前的灰度值通过某种计算关系映射到另一个灰度值。

具体算法就是将该像素点灰度值的累计概率 x 灰度值的取值范围(0-255),即是映射后的灰度值,然后取整,得到最终的该像素点均匀化后的灰度值。

(累计概率就是自己灰度值的概率加上前一个灰度值的概率)

opencv做图像直方图均匀化

代码非常简单:

复制代码
img = cv2.imread("img1.jpg", cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)    # 直方图均匀化
plt.hist(equ.ravel(), 256)
plt.show()

但是这种均匀化是整个图进行均匀化,有时候会导致细节丢失,如下图:

那有没有一种方法可以让图像分成"九宫格"(类似),然后每个格子单独均匀化呢?

有的,兄弟,有的,opencv中给了现成的自适应直方图均匀化。

自适应直方图均匀化

复制代码
img = cv2.imread("img1.jpg", cv2.IMREAD_GRAYSCALE)
# 全图直方图均匀化
equ = cv2.equalizeHist(img)
# 自适应直方图均匀化
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
res_clahe = clahe.apply(img)

res = np.hstack((img, equ, res_clahe))
cv2.imshow("res", res)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果对比:

相关推荐
毋语天2 分钟前
FastAPI 进阶实战:请求体、文件上传、响应模型与数据校验
python·fastapi·api开发·数据校验·pydantic
T.i.s3 分钟前
parall scan(并行扫描)通俗理解
人工智能·深度学习
珠海西格电力4 分钟前
零碳园区的碳排放指标计算的实操步骤
大数据·运维·人工智能·物联网·能源
云和数据.ChenGuang15 分钟前
基于鲲鹏 HPC 的 AI 对话机器人架构设计与技术实现
人工智能·数据分析·机器人·pandas·数据预处理·数据训练
weixin_5118404718 分钟前
2026年5月4日 OCS技术方案路线选择与优劣深度调研报告
网络·人工智能
h64648564h26 分钟前
CANN 昇腾训练食谱全景解读:cann-recipes-train 架构与使用指南
人工智能·深度学习
qcx2329 分钟前
【AI Daily】Arxiv论文研读Top5 | 2026-05-23
人工智能
逐米时代38 分钟前
成都制造企业采购合同风险审核,AI智能体该查哪些条款?
大数据·人工智能
Peter·Pan爱编程42 分钟前
10. new_delete 不是 malloc_free 的包装
c++·人工智能·算法
IT_陈寒1 小时前
Vue的computed属性怎么突然不更新了?
前端·人工智能·后端