• 直方图与直方图均衡化


            今天,花了些时间研究了一下直方图和直方图均衡化的一些操作,对我这个小白来说,虽然是原理简单的知识,但在实操时却遇到很多问题,真实不太容易,所以这里记录一下。

            主要完成了以下的实操:

    1. 直方图的处理
      1. cv2处理直方图(灰度图和彩图)
      2. pyplot处理直方图(灰度图和彩图)
    2. 直方图均衡化
      1. 灰度图均衡化
      2. 彩图均衡化
      3. 均衡化自实现,并于cv结果比较

    下面详细来大概记录一下。

    直方图展示(灰度图和彩图)

    对于直方图的处理,有cv2和pyplot2种常用的方式,接口定义分别为

    cv2.calcHist()和plt.Hist(),这部分就是理解现有接口定义,直接调用即可,直接上代码。

    1. '''
    2. calcHist—计算图像直方图
    3. 函数原型:calcHist(images, channels, mask, histSize, ranges, hist=None, accumulate=None)
    4. images:图像矩阵,例如:[image]
    5. channels:通道数,例如:0
    6. mask:掩膜,一般为:None
    7. histSize:直方图大小,一般等于灰度级数
    8. ranges:横轴范围
    9. '''
    10. import cv2
    11. import matplotlib.pyplot as plt
    12. color = cv2.imread("..//..//dataset//lena.png", 1)
    13. cv2.imshow('color', color)
    14. gray = cv2.cvtColor(color, cv2.COLOR_BGR2GRAY)
    15. cv2.imshow('gray', gray)
    16. img_Gray = cv2.imread('..//..//dataset//lena.png', cv2.IMREAD_GRAYSCALE)
    17. # cv2.cvtColor(img)
    18. cv2.imshow('lenaGray', img_Gray)
    19. '''cv2操作直方图'''
    20. # 这里注意,全部的参数,都要[]形式,否则数据不正确
    21. # cv2 灰度直方图
    22. cv2_hist = cv2.calcHist([img_Gray], [0], None, [256], [0, 255])
    23. plt.plot(cv2_hist)
    24. plt.show()
    25. # cv2 各通道彩色直方图
    26. color_hist0 = cv2.calcHist([color], [0], None, [256], [0, 255])
    27. color_hist1 = cv2.calcHist([color], [1], None, [256], [0, 255])
    28. color_hist2 = cv2.calcHist([color], [2], None, [256], [0, 255])
    29. plt.plot(color_hist0)
    30. plt.plot(color_hist1)
    31. plt.plot(color_hist2)
    32. plt.show()
    33. '''plt直接显示直方图'''
    34. # 灰度直方图
    35. plt.hist(img_Gray.ravel(), 256)
    36. plt.show()
    37. # 彩色直方图
    38. # 彩色直方图
    39. plt.hist(color[:, :, 0].ravel(), 256)
    40. plt.hist(color[:, :, 1].ravel(), 256)
    41. plt.hist(color[:, :, 2].ravel(), 256)
    42. plt.show()
    43. cv2.waitKey(0)
    44. cv2.destroyAllWindows()

    这里需要特别注意一下的是,calcHist的参数,所有的参数都以[]形式进行传递,当mask为None时,直接以None替代,否则,结果不正确。

    上面只是使用pyplot简单展示了数据,关于pyplot的使用,其实可以做到很多好看的样式,有需要的同学可以去学习一下。


    然后,主要说一下直方图均衡化的操作,因为在实际运用种,均衡化是用的较多的。

    操作其实也简单,直接调用接口即可,上代码看一下

    1. img = cv2.imread('..//..//dataset//lena.png')
    2. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    3. # gray图像均衡化
    4. dst = cv2.equalizeHist(gray)
    5. hist_src = cv2.calcHist([gray], [0], None, [256], [0, 255])
    6. hist_dst = cv2.calcHist([dst], [0], None, [256], [0, 255])
    7. # plt.plot(hist_dst)
    8. # plt.show()
    9. # print(type(hist_src))
    10. cv2.imshow('hist_origin_Equalization', np.hstack([gray, dst]))
    11. # 多通道图像均衡化
    12. # 注意该方法只能对单通道图像进行处理,因此,对多通道图像需要先split进行处理,之后再merge进行合并
    13. (sb, sg, sr) = cv2.split(img)
    14. db = cv2.equalizeHist(sb)
    15. dg = cv2.equalizeHist(sg)
    16. dr = cv2.equalizeHist(sr)
    17. dstImg = cv2.merge((db, dg, dr))
    18. cv2.imshow('EqualizationImage', np.hstack([img, dstImg]))
    19. # cv2.waitKey(0)
    20. # cv2.destroyAllWindows()

    这里我们提一下,均衡化操作,对应的都是单通道数据,因此,如果是彩色图片进行处理时,我们可以通过split()函数先将其拆分,处理完成后,再通过merge()函数将其合并即可。

    这里,附上结果图看一下,可以看到,效果还是蛮明显的。


    到这里后,需要想要详细理解均衡化的原理,可以试着自己实现一下均衡化操作。

    下面,是我自己实现的均衡化操作,过程种的变量是随意定义的,可以根据流程理解一下

    1. # 自实现均衡化
    2. # 排序-求对应数量-求累计数量-计算结果-生成目标图像
    3. def histEqualization(img):
    4. points = list(img.flatten())
    5. sets = list(set(points))
    6. sets.sort() # 默认升序
    7. point_count = [points.count(i) for i in sets]
    8. sum = [np.sum(point_count[0:i]) for i in range(len(point_count))]
    9. level = [i / len(points) for i in sum]
    10. # 很多推导公式,这里显示是(比例*256)-1,这样会得到很多的负值情况,但我认为直接*256即可,因为其取值范围已经是256个了。
    11. dp = [int(l * 256) for l in level]
    12. dst = [dp[sets.index(i)] for i in points]
    13. dstImg = np.array(dst,np.uint8).reshape((img.shape[0], img.shape[1]))
    14. return dstImg
    15. # 自实现均衡化方法
    16. dstCustom=histEqualization(gray)
    17. cv2.imshow('customEqualization',dstCustom)
    18. # 从比较结果可以看出自实现的效果和cv的效果还是有很大差别的。
    19. print(np.sum(dstCustom==dst))
    20. print(np.sum(dstCustom.flatten()==dst.flatten()))
    21. # 彩色图像分开调用多次即可

    这里的话,提2点:

    1.通过我自定义的方法实现的结果与cv的结果有较大的却别,图像只有200多点相同(应该是cv做了一些优化操作),但整体效果看着几乎没差别。

    2.在实际使用时,推荐使用cv方法直接处理。

    3.关于list的sort操作,其sort是针对自身list进行,可以排序后赋值给其他变量,但不能将排序直接赋值给新变量,这样返回为None

    1. a=[1,2,3,4,5]
    2. a.sort(reverse=Ture)
    3. c=a
    4. # 此时,c与a相同,均为[5,4,3,2,1]
    5. b=a.sort()
    6. # 此时,b为None,不能直接赋值


    以上即今天的全部内容,感觉对基础不熟悉,在实操时影响真的很大,还是得注重平时多练习,也得加强一下对python得掌握了,虽然简单,但实际开发应用与简单得语法测试还是天差地别的,加油!

  • 相关阅读:
    java计算机毕业设计图书借阅系统演示录像源程序+mysql+系统+lw文档+远程调试
    Sentinel 安装启动
    gstreamer registry文件
    linux内核分析:探究x86
    ActiveReportsJS 在 React 应用程序中添加和自定义查看器
    互联网曝光文明城市监督举报小程序开发
    FX5800计算器测量程序集2.4
    Xcode工程统计代码行数(Swift版)
    Android自定义控件(四) 自定义百度贴吧水波纹Loading效果
    图论---图的存储
  • 原文地址:https://blog.csdn.net/xiansenLee/article/details/126388893