• Opencv——直方图、掩膜、直方图均衡化详细介绍及代码实现


    一、图像直方图

    1.1 定义:

    图像直方图是图像的基本属性之一,也是反映图像像素数据分布的统计学特征,其横坐标代表了图像像素点在[0,255]范围中,纵坐标代表图像像素点出现的个数或百分比。如图:

     1.2 函数:cv2.calcHist([img1],[channels],mask,histSize,ranges)

    img:输入图像

    channels:通道,如果输入的是灰度图,则此参数为[0],如果是彩色图,传入参数为[0]或[1]或[2]分别对应BGR。

    mask:掩膜统计整幅图的直方图就是None。如果画某一部分直方图,需要制作一个掩模图像并使用。掩模大小和img一样的np数组,需要的部分为255,不需要的部分为0.

    histSize:直方图bin的数目,[0,256]所以就是256。

    ranges:像素范围[0,256]顾头不顾尾啦。

    1.3 代码实现:

    (1)准备工作加灰度图显示:

    1. import cv2
    2. import numpy as np
    3. import matplotlib.pyplot as plt
    4. %matplotlib inline
    5. #显示图像
    6. def cv_show(name,img):
    7. cv2.imshow(name,img)
    8. cv2.cv2.waitKey(0)
    9. cv2.destroyAllWindows()
    10. #导入图像
    11. img1=cv2.imread("C:/Users/bwy/Desktop/lena.bmp",0)
    12. hist=cv2.calcHist([img1],[0],None,[256],[0,256])
    13. print(hist.shape)
    14. plt.hist(img.ravel(),256)
    15. plt.show()

    结果如图(灰度图):

     (2)彩色图三个不同的通道:

    1. img=cv2.imread("C:/Users/bwy/Desktop/7.png")
    2. cv_show('img',img)
    3. color=('b','g','r')
    4. for i,col in enumerate(color):
    5. histr=cv2.calcHist([img],[i],None,[256],[0,256])
    6. plt.plot(histr,color=col)
    7. plt.xlim([0,256])

    结果如图:

     从上面两个图我们就可发现直方图很不均匀,可以比喻成不是矮胖的,所以我们接下来进行图像直方图均衡化。但是,在此之前我们在学习一下掩膜。

    二、掩膜(mask)

    2.1掩模mask思想:

    掩模的大小和原图像大小一致。掩模中只有两部分,0和255,掩模中白色部分覆盖到的区域保留原图,黑色部分覆盖到的区域置为0。如果我们读入彩图,在构建np数组时,需要舍弃第三个维度,即通道。保留前两个维度img.shape[:2],掩模的size和原图像相同。由于mask是一个数组,可以使用切片方法将保留的位置变成白色255。

    2.2代码:

    1. img.shape[:2]#(420, 607)
    2. #创建mast
    3. mask=np.zeros(img.shape[:2],np.uint8)
    4. mask[100:300,200:400]=255
    5. cv_show('mask',mask)

    结果如图:

    1. masked_img=cv2.bitwise_and(img1,img1,mask=mask)
    2. cv_show('masked_img',masked_img)

     结果如图:

     2.3掩膜过程对比

    1. plt.subplot(221),plt.imshow(img1)
    2. plt.subplot(222),plt.imshow(mask)
    3. plt.subplot(223),plt.imshow(masked_img)
    4. plt.subplot(224),plt.plot(hist_full),plt.plot(hist_mask)
    5. plt.xlim([0,256])
    6. plt.show()

    结果如图:

    三、直方图均衡化

    通过改变图像的直方图,来改变图像中各像素的灰度,用于增强局部的对比度而不影响整体的对比度。这种方法对于背景和前景都太亮或者太暗的图像非常有用。

    3.1对图像整体进行均衡化

    (1)进行均衡化后直方图前后对比显示:

    1. img=cv2.imread("C:/Users/bwy/Desktop/lena.bmp",0)
    2. plt.hist(img.ravel(),256)
    3. plt.show()
    4. equ=cv2.equalizeHist(img)
    5. plt.hist(equ.ravel(),256)
    6. plt.show()

    结果对比图:

              

     (2)进行均衡化后图像前后对比显示:

    1. img=cv2.imread("C:/Users/bwy/Desktop/lena.bmp",0)
    2. equ=cv2.equalizeHist(img)
    3. res=np.hstack((img,equ))
    4. cv_show('res',res)

    结果如图:(明显更亮了,好漂亮(●'◡'●)) 

     但是呢,这个方法也存在微瑕,那看一下如果我用下面这张图你就会发现了:

    我们会发现这个帅锅的脸太亮了,我们观察不到细节了,细节丢失了,所以这个问题我们如何解决呢? 

     3.2 自适应均衡化

    1、定义:

    整幅图像会被分成很多小块,然后再对每一个小块分别进行直方图均衡化缺点是:如果有噪声的话,噪声会被放大。为了避免这种情况的出现要使用对比度限制。

    2、代码:

    1. img2=cv2.imread("C:/Users/bwy/Desktop/1.png",0)
    2. img2.shape#(508, 672)
    3. img3=cv2.resize(img2,(400,300))
    4. equ1=cv2.equalizeHist(img3)
    5. clahe=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
    6. res_clahe=clahe.apply(img3)
    7. res=np.hstack((img3,equ1,res_clahe))
    8. cv_show('res',res)

    结果如图:

  • 相关阅读:
    免费开源的区域屏幕录制(gif转换)工具(支持编辑功能)
    Day43:LeedCode 1049. 最后一块石头的重量 II 494. 目标和 474.一和零
    9.3 链表从指定节点插入新节点
    基于ssm的停车场管理系统
    解密JavaChassis3:易扩展的多种注册中心支持
    7. SQL中函数的简介
    1行Python代码,合并100个Excel文件,原来这么方便?
    嵌入式系统 期末复习提纲
    Mojo 语言官网
    包 类 包的作用域
  • 原文地址:https://blog.csdn.net/m0_72662900/article/details/127819746