OpenCV之直方图基础与均衡化

OpenCV之直方图基础与均衡化 tomato 2023-12-07 18:06:59 361

一、直方图基础

从统计学角度来看,直方图用于统计图像内各个灰度级出现的次数,直方图的横坐标表示图像的灰度级,纵坐标表示像素灰度级的数量。在使用OpenCv处理直方图时,应注意以下三个概念:

(1) RANGE:要统计的灰度级范围。直方图中像素的灰度级范围一般为[0, 255],0表示黑色,255表示白色。

(2) BINS:灰度级的分组数量。在处理直方图时,将灰度级按一定范围进行划分得到的子集数量为BINS。例如,灰度图像的灰度级范围为[0, 255],按16个灰度级分为一组,可分成16个子集,则BINS为16。

(3) DIMS:绘制直方图时采集的参数数量。一般的直方图只采集灰度级,所以DIMS为1。

1.用hist()函数绘制直方图

matplotlib.pyplot.hist()函数可根据图像绘制直方图,其基本格式如下:

img = matplotlib.pyplot.hist(src, bins)

src为用于绘制直方图的图像数据, 必须是一维数组, 通常, OpenCV中的BGR图像是三维数组, 可用ravel()函数将其转换为一维数组
bins为灰度级分组数量


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

img = plt.imread('gate.jpg')

plt.figure(figsize = (25,10))
plt.subplot(1, 2, 1)
plt.axis('off')
plt.title('original')
plt.imshow(img)

plt.subplot(1, 2, 2)
plt.hist(img.ravel(), 256)
plt.title('hist')
plt.show()

2.用calcHist()函数查找直方图:

可使用OpenCV的cv2.calcHist()函数查找直方图,再利用matplotlib.pyplot的plot()函数绘制直方图。cv2.calcHist()函数的基本格式如下:

hist =cv2.calcHist(image, channels, mask, histSize, ranges)

参数说明如下

  • hist为返回的直方图, 是一个一维数组, 其大小为256, 保存了原图像中各个灰度级的数量

  • image为原图像, 实际参数需要用方括号括起来

  • channels为通道编号, 灰度图像的通道编号为[0], BGR图像通道的编号为[0][1][2]

  • mask为掩模图像, 为None时统计整个图像, 否则统计部分图像

  • histSize为BINS值, 实际参数需要用方括号括起来, 如[256]

  • ranges为像素值范围, 8位灰度图像为[0,256]

img = cv2.imread('gate.jpg')
cv2.imshow('oribinal', img)

histb = cv2.calcHist([img], [0], None, [256], [0, 255])
histg = cv2.calcHist([img], [1], None, [256], [0, 255])
histr = cv2.calcHist([img], [2], None, [256], [0, 255])

plt.plot(histb, color='b')
plt.plot(histg, color='g')
plt.plot(histr, color='r')
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

3.应用掩模的直方图

cv2.calcHist()函数的mask参数用于指定掩模图像。掩模图像为黑底,其中的白色区域可视为透明区域,将其覆盖到原图像上,原图像中可显示出来的部分为掩模结果图像。指定掩模图像时,cv2.calcHist()函数只计算掩模结果图像的直方图。


img = cv2.imread('gate.jpg')  
cv2.imshow('original', img)  

h, w, c = img.shape
mask = np.zeros((h, w), np.uint8)      #按原图大小创建一幅黑色图像

w1 = np.int0(w / 4)
w2 = np.int0(w * 0.75)
h1 = np.int0(h / 4)
h2 = np.int0(h * 0.75)
mask[h1 : h2, w1 : w2] = 255           #设置掩模白色区域
cv2.imshow('mask', mask)               #显示掩模图像

histb=cv2.calcHist([img],[0],mask,[256],[0,255])   #计算B通道直方图
histg=cv2.calcHist([img],[1],mask,[256],[0,255])   #计算G通道直方图
histr=cv2.calcHist([img],[2],mask,[256],[0,255])   #计算R通道直方图

plt.plot(histb,color='b')               #绘制B通道直方图,蓝色
plt.plot(histg,color='g')               #绘制G通道直方图,绿色
plt.plot(histr,color='r')               #绘制R通道直方图,红色
plt.show()                              #显示直方图

cv2.waitKey(0)
cv2.destroyAllWindows()

图像的掩模:


图像掩模的直方图:

4.NumPy中的直方图

NumPy的histogram()函数可以用于计算直方图,其基本格式如下

hist, bin_edges = np.histogram(src, bins,range)hist为返回的直方图
bin_edges为返回的灰度级分组数量边界值
src为原图转换成的一维数组
bins为灰度级分组数量range为像素值范围
img = cv2.imread('gate.jpg')
cv2.imshow('original', img)

histb, e1 = np.histogram(img[0].ravel(), 256,[0, 255])
histg, e2 = np.histogram(img[1].ravel(), 256,[0, 255])
histr, e3 = np.histogram(img[2].ravel(), 256,[0, 255])

plt.plot(histb,color='b')               #绘制B通道直方图,蓝色
plt.plot(histg,color='g')               #绘制G通道直方图,绿色
plt.plot(histr,color='r')               #绘制R通道直方图,红色
plt.show()

cv2.waitKey(0)
cv2.destroyAllWindows()

二.直方图均衡化

1.原理与应用

“直方图均衡化”是把原始图像的灰度直方图从比较集中的某个灰度区间变成在更广泛灰度范围内的分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。这种方法提高图像整体的对比度,特别是有用数据的像素值分布比较接近时,在X光图像中使用广泛,可以提高骨架结构的显示,另外在曝光过度或不足的图像中可以更好的突出细节。

使用opencv:进行直方图统计时,使用的是:

API:

dst = cv.equalizeHist(img)

参数如下

| dst | 均衡化后的结果 |

| img | 灰度图像 |

示例

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

# 解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 1.直接以灰度图的方式读入
img = cv.imread('./images/e.jpg', 0)
# 2.均衡化处理
dst = cv.equalizeHist(img)
# 3.结果展示
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8), dpi=100)
axes[0, 1].imshow(img, cmap=plt.cm.gray)
axes[0, 1].set_title("原图")
axes[1, 1].imshow(dst, cmap=plt.cm.gray)
axes[1, 1].set_title("均衡化图")
plt.show()

结果如下

2.自适应直方图均衡化

为了提高图像的局部对比度,可将图像分成若干子块,对对子块进行直方图均衡化,这就是自适应直方图均衡化。
API:

cv.crateCLAHE(clipLimit,tileGridSize)

参数

示例


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

# 解决中文显示问题
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 1.直接以灰度图的方式读入
img = cv.imread('./images/e.jpg', 0)

# 2.创建一个自适应均衡化的对象,并应用于图像
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)
# 3,图像展示
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img, cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(cl1, cmap=plt.cm.gray)
axes[1].set_title("自适应均衡化后的结果“")
plt.show()

结果如下

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
tomato
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
tomato
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区