OpenCv机器学习爱好者数字图像处理与计算机视觉(python)

在Opencv中直方图的绘制

2019-07-15  本文已影响0人  陨星落云

直方图

什么是直方图呢?

直方图是对数据集合统计,并将统计结果分布于一系列定义的bins中。这里的数据不仅仅是灰度值,统计数据可能是任何能够有效描述图像的特征,例如颜色、梯度/边缘、形状、纹理、局部特征点、视觉词汇等。

灰度直方图

通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的点的数目。
灰度直方图其实就是对图像的另一种解释。通过直方图我们可以对图像的对比度,亮度,灰度分布等有一个直观的认识。几乎所有的图像处理软件都提供了直方图分析功能。在这里,直方图是根据灰度图像绘制的,而不是彩色图像。直方图的左边区域像是了暗一点的像素数量,右侧显示了亮一点的像素的数量。

灰度直方图.png

使用OpenCV 统计直方图函数 cv2.calcHist 可以帮助我们统计一幅图像的直方图。

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

参数意义如下:

例子:以灰度格式加载一幅图像并统计图像的直方图

import cv2
import matplotlib.pyplot as plt
import numpy as np

def img_show(name,img):
    """matplotlib图像显示函数
    name:字符串,图像标题
    img:numpy.ndarray,图像
    """
    if len(img.shape) == 3:
        img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    plt.imshow(img,'gray')
    #plt.xticks([])
    #plt.yticks([])
    plt.xlabel(name,fontproperties='FangSong',fontsize=12)
    

if __name__=="__main__":

    img1 = cv2.imread("cute-dog.jpg",0)
    #别忘了中括号[img1],[0],None,[256],[0,256],只有mask没有中括号
    hist = cv2.calcHist([img1],[0],None,[256],[0,256])
      
    plt.figure(figsize=(12,8),dpi=80)
    plt.subplot(121)
    img_show('原图',img1)
    plt.subplot(122)
    plt.plot(hist)
    plt.xlim([0,256])
    plt.ylim([0,800000])
    plt.xlabel('直方图',fontproperties='FangSong',fontsize=12)
直方图1.png

使用 Matplotlib Matplotlib 中有直方图绘制函数:matplotlib.pyplot.hist()它可以直接统计并绘制直方图。

img1 = cv2.imread("cute-dog.jpg",0)

plt.figure(figsize=(12,8),dpi=80)
plt.subplot(121)
img_show('原图',img1)
plt.subplot(122)
plt.hist(img1.ravel(),256,[0,256])
plt.xlim([0,256])
plt.xlabel('直方图',fontproperties='FangSong',fontsize=12)
直方图2.png

例子:绘制BGR通道直方图

img1 = cv2.imread("cute-dog.jpg")
color = ('b','g','r')
# 对一个列表或数组既要遍历索引又要遍历元素时
# 使用内置enumerrate函数会有更加直接,优美的做法
# enumerate会将数组或列表组成一个索引序列。
# 使我们再获取索引和索引内容的时候更加方便
for i,col in enumerate(color):
    print(i)
    print(col)
    hist = cv2.calcHist([img1],[i],None,[256],[0,256])
    plt.plot(hist,color=col)
    plt.xlim([0,256])
    plt.ylim([0,800000])
plt.show()
直方图3.png
img1 = cv2.imread("cute-dog.jpg")
color = ('b','g','r')

for i,col in enumerate(color):
    
    plt.hist(img1[:,:,i].ravel(),256,[0,256],color=col,alpha=1)
    plt.xlim([0,256])
    plt.ylim([0,800000])
plt.show()
直方图4.png

使用掩模
要统计图像某个局部区域的直方图只需要构建一副掩模图像。将要统计的部分设置成白色,其余部分为黑色,就构成了一副掩模图像。然后把这个掩模图像传给函数就可以了。

例子:统计图像某个局部区域的直方图

img1 = cv2.imread("cute-dog.jpg")
img = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)

# 创建掩膜
mask = np.zeros(img.shape[:2],np.uint8)
mask[1000:4000,100:3200] = 255
img_mask = cv2.bitwise_and(img,img,mask =mask)

# 创建一个掩膜和一个无掩膜的直方图
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img_mask],[0],mask,[256],[0,256])

plt.figure(figsize=(10,8),dpi=80)
plt.subplot(221)
plt.imshow(img,'gray')
plt.subplot(222)
plt.imshow(mask,'gray')
plt.subplot(223)
plt.imshow(img_mask,'gray')
plt.subplot(224)
plt.plot(hist_full,label='original')
plt.plot(hist_mask,label='img_mask')
plt.legend()
plt.xlim([0,256])
plt.ylim([0,800000])
局部直方图.png

参考资料:
网址:Matplotlib基础教程
书籍:《数字图像处理》《OpenCV-Python-Toturial-中文版》

上一篇 下一篇

猜你喜欢

热点阅读