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()

效果对比:

相关推荐
黄啊码9 小时前
Coze新品实测:当AI开始像产品经理思考,我和程序员吵架的次数少了
人工智能·agent·coze
cRack_cLick9 小时前
pandas库学习02——基本数据清洗
python·pandas
jie*9 小时前
小杰机器学习(six)——概率论——1.均匀分布2.正态分布3.数学期望4.方差5.标准差6.多维随机变量及其分布
人工智能·机器学习·概率论
yubo05099 小时前
YOLO系列——实时屏幕检测
开发语言·windows·python
挽安学长9 小时前
通过 gaccode在国内使用ClaudeCode,Windows、Mac 用户配置指南!
人工智能
Monkey的自我迭代9 小时前
背景建模(基于视频,超炫)项目实战!
opencv·计算机视觉·音视频
唐某人丶9 小时前
教你如何用 JS 实现 Agent 系统(3)—— 借鉴 Cursor 的设计模式实现深度搜索
前端·人工智能·aigc
weixin_457340219 小时前
RTX5060 Ti显卡安装cuda版本PyTorch踩坑记录
人工智能·pytorch·python
Stanford_11069 小时前
关于物联网的基础知识(四)——国内有代表性的物联网平台都有哪些?
人工智能·物联网·微信·微信公众平台·twitter·微信开放平台
偶尔贪玩的骑士9 小时前
Machine Learning HW4 report: 语者识别 (Hongyi Lee)
人工智能·深度学习·机器学习·self-attention