opencv实现直方图均衡 opencv统计图像灰度直方图_灰度值


目录

  • 前言
  • 正文
  • 基本概念
  • 直方图的绘制
  • 使用掩模得出某部分的直方图
  • 掩模的应用
  • 掩模的效果图及代码
  • 函数
  • cv.calcHist()
  • 参考

前言

目标
• 使用 OpenCV 或 Numpy 函数计算直方图
• 使用 Opencv 或者 Matplotlib 函数绘制直方图
• 将要学习的函数有:cv2.calcHist(),np.histogram()
作用
通过直方图你可以对整幅图像的灰度分布有一个整体的 了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的 点的数目。

正文

基本概念

BINS:把原来的 256 个值等分成 16 小组,取每组的 总和。而这里的每一个小组就被成为 BIN.
DIMS:表示我们收集数据的参数数目。在本例中,我们对收集到的数据 只考虑一件事:灰度值。所以这里就是 1。
RANGE:就是要统计的灰度值范围,一般来说为 [0,256],也就是说所 有的灰度值

直方图的绘制

第一种方法:plt.hist()

matplotlib.pyplot.hist(X,BINS) 能够绘制直方图,X是一维数据源,通常读入图片后需要用ravel函数将二维数组降为一维。

效果图

opencv实现直方图均衡 opencv统计图像灰度直方图_灰度值_02


code

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/lena.jpg")
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
plt.hist(hsv.ravel(),256)
plt.show()
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()

第二种方法

效果图

opencv实现直方图均衡 opencv统计图像灰度直方图_灰度值_03


code

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

src = cv.imread("../../images/lena.jpg")
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
### 第二种方法
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
plt.imshow(hist, interpolation='nearest')
plt.show()
# cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
# cv.imshow('input image', src)
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()

第三种方法

效果图

opencv实现直方图均衡 opencv统计图像灰度直方图_opencv_04


code

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

src = cv.imread("../../images/lena.jpg")
color = ('b','g','r')

for i,col in enumerate(color):
    histr = cv.calcHist([src],[i],None,[256],[0,256])
    plt.plot(histr,color=col)
    plt.xlim([0,256])
plt.show()

cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow('input image', src)
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()

使用掩模得出某部分的直方图

掩模的应用

掩膜是用选定的图像、图形或物体,对要处理的图像进行遮挡,来控制图像 处理的区域。
在数字图像处理中,我们通常使用二维矩阵数组进行掩膜。掩膜是由0和1组成一个二进制图像,利用该掩膜图像要处理的图像进行掩膜,其中1值的区域被处理,0 值区域被屏蔽,不会处理。
掩膜的主要用途是:

  1. 提取感兴趣区域:用预先制作的感兴趣区掩模与待处理图像进行”与“操作,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
  2. 屏蔽作用:用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
  3. 结构特征提取:用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
    特殊形状图像制作

掩模的效果图及代码

效果圖

opencv实现直方图均衡 opencv统计图像灰度直方图_opencv实现直方图均衡_05


注意,图像应为灰度图再进行绘制。图像直方图(Image Histogram)是用以表示数字图像中亮度分布的直方图。标绘了图像中每个亮度值的像素个数。这种直方图中,横坐标的左侧为较暗的区域,而右侧为较亮的区域。因此一张较暗图片的直方图中的数据多集中于左侧和中间部分,而整体明亮、只有少量阴影的图像则相反。

code:

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


src = cv.imread("../../images/lena.jpg")
gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)#切记要转为灰度图
#create a mask
mask = np.zeros(gray.shape[:2],np.uint8)
mask[100:300,100:400] = 255#将部分mask设为255
masked_img = cv.bitwise_and(gray,gray,mask=mask)#这个标识的是将gray,与gray在mask的这部分上进行与操作,就可以得出那部分的图像
cv.imshow("masked_img",masked_img)
#将这两种直方图进行图形的显示
cal_fullHist = cv.calcHist([gray],[0],None,[256],[0,256])#channels: 如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
cal_maskHist = cv.calcHist([gray],[0],mask,[256],[0,256])#这里mask的大小,如果没有mask就直接设为None,有就直接设置就可以了

plt.subplot(221),plt.imshow(gray,"gray")#注意,前面三个的后面那个名字要是一样的,不然会出错。
plt.subplot(222),plt.imshow(mask,"gray")
plt.subplot(223),plt.imshow(masked_img,"gray")
plt.subplot(224),plt.plot(cal_fullHist),plt.plot(cal_maskHist)
plt.xlim([0,256])
plt.show()

cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow('input image', src)
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口

cv.destroyAllWindows()

函数

cv.calcHist()

cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
  1. images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该 用中括号 [] 括起来,例如:[img]。
  2. channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图 像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像 的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
  3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如 果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并 使用它。(后边有例子)
  4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
  5. ranges: 像素值范围,通常为 [0,256]

参考

  1. OpenCV-Python-Tutorial-中文版20160814.pdf
  2. OpenCV:直方图、灰度直方图、掩膜、直方图均衡化、