运用OpenCV,Numpy核算直方图,Matplot制作直方图及分析

这篇博客将介绍如何运用Python,OpenCV,Numpy函数核算直方图,并运用 OpenCV 和 Matplotlib 函数制作直方图,并对直方图进行分析。

经过检查图画的直方图,能够直观地了解该图画的对比度、亮度、强度散布等。

1. 作用图

原始图如下:

使用OpenCV,Numpy计算直方图,Matplot绘制直方图及分析

灰度图直方图作用如下:

能够看到左边区域显现图画中较暗像素的数量,右侧区域显现较亮像素的数量。从直方图中能够看到暗区、亮区均不多,并且中间色调(中间规模的像素值,例如 170/210 左右)的数量非常多。

使用OpenCV,Numpy计算直方图,Matplot绘制直方图及分析
BGR三通道的直方图作用图下:
使用OpenCV,Numpy计算直方图,Matplot绘制直方图及分析
原始图 VS Mask遮罩 VS Mask图画 VS 混合直方图如下: 在第4个直方图中,蓝线表明完好图画的直方图,红线表明遮罩区域的直方图。
使用OpenCV,Numpy计算直方图,Matplot绘制直方图及分析

2. 原理

直方图能够帮助全面了解图画的强度散布。 最基本的直方图是灰度图画直方图,在 X 轴上具有像素值(规模从 0 到 255)和 Y 轴上图画中相应像素数的图。

核算直方图的3种方法:

  • hist = cv2.calcHist([img],[0],None,[256],[0,256])
  • hist,bins = np.histogram(img.ravel(),256,[0,256])
  • np.bincount(img.ravel(),minlength=256)

其间cv2的方法比np.histogram快40倍; np.bincount比np.histogram快10倍,因而优先运用cv2.calHist()方法;

制作直方图的2种方法:

  • matplot核算直方图并制作:plt.hist(img.ravel(),256,[0,256]); plt.show()
  • matplot的简单制作方法:histr = cv2.calcHist([img],[i],None,[256],[0,256]) plt.plot(histr,color = col) plt.xlim([0,256])

3. 源码

3.1 直方图3种核算方法和2种制作方法

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('ml.jpg', 0)
# cv核算直方图
# cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
# - img:要核算直方图的图画
# - channels:通道值,如果传入灰度图为0,彩色图[0][1][2]分别核算BGR通道
# - mask:蒙版,并非为整个图核算直方图
# - histSize:x轴分多少个规模
# - ranges: 值的规模,通常是[0,256]
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
# numpy核算直方图
#  np.bincount() 比 np.histogram() 大约快10倍
#  cv2.calHist() 比 np.histogram() 大约快40倍
hist, bins = np.histogram(img.ravel(), 256, [0, 256])
hist = np.bincount(img.ravel(), minlength=256)
# 制作直方图法1:matplot
img = cv2.imread('ml.jpg', 0)
plt.hist(img.ravel(), 256, [0, 256])
plt.show()
# 制作直方图法2:matplot一般制作方法
img = cv2.imread('ml.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])
plt.show()

3.2 Mask遮罩图画直方图

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('ml.jpg', 0)
# 构造一个mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv2.bitwise_and(img, img, mask=mask)
# 核算整个图直方图以及mask的直方图
hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])
plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask, 'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full, color='b'), plt.plot(hist_mask, color='r')
plt.xlim([0, 256])
plt.show()

参考

  • docs.opencv.org/3.0-beta/do…