OpenCV - 直方图绘制(Python实现)

本文介绍了如何使用OpenCV和Numpy在Python中统计与绘制图像直方图,包括直方图的基本原理、相关术语如BINS和RANGE,并展示了如何应用掩模来统计图像特定区域的直方图。
摘要由CSDN通过智能技术生成

原理

  直方图的 x 轴是灰度值(0 到 255), y 轴是图片中具有同一个灰度值的点的数目。直方图其实就是对图像的另一种解释。通过直方图我们可以对图像的对比度,亮度,灰度分布等有一个直观的认识。

相关术语

BINS: 上面的直方图显示了每个灰度值对应的像素数。
DIMS:表示我们收集数据的参数数目。如果我们对收集到的数据只考虑一件事:灰度值。所以这里就是 1。
RANGE:就是要统计的灰度值范围,一般来说为 [0, 256],也就是说所有的灰度值

统计直方图

1.使用 OpenCV

cv2:calcHist(images; channels; mask; histSize; ranges[; hist[; accumulate]])
参数**
images原图像(图像格式为 uint8 或 float32)
当传入函数时应该用中括号 [] 括起来,例如: [img]
channels:同样需要用中括号括起来
灰度图值就是 [0];彩色图像 [0], [1], [2] 分别对应B, G, R
mask:掩模图像
要统计整幅图像的直方图就把它设为 None
histSizeBIN 的数目
也应该用中括号括起来,例如: [256]
ranges:像素值范围,通常为 [0, 256]

2.使用 Numpy

#img.ravel() 将图像转成一维数组,这里没有中括号。
hist,bins = np.histogram(img.ravel(),256,[0,256])
hist=np.bincount(img.ravel(), minlength=256)#速度较上函数快十倍左右

  hist 与上面计算的一样。但是这里的 bins 是 257,因为 Numpy 计算bins 的方式为: 0-0.99,1-1.99,2-2.99 等。所以最后一个范围是 255-255.99。为了表示它,所以在 bins 的结尾加上了 256。但是我们不需要 256,到 255就够了。

绘制直方图

  Matplotlib 中有直方图绘制函数:matplotlib.pyplot.hist()

   matplotlib.pyplot.hist(  
    x, bins=10, range=None, normed=False,   
    weights=None, cumulative=False, bottom=None,   
    histtype=u'bar', align=u'mid', orientation=u'vertical',   
    rwidth=None, log=False, color=None, label=None, stacked=False,   
    hold=None, **kwargs)  
参数**
x这个参数是指定每个bin(箱子)分布的数据,对应x轴
bins指定bin(箱子)的个数,也就是总共有几条条状图
normed这个参数指定密度,也就是每个条状图的占比例比,默认为1
color这个指定条状图的颜色

  下面对这个图像进行统计直方图。
在这里插入图片描述

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
plt.hist(img.ravel(),256,[0,256],);
plt.show()

在这里插入图片描述
  或者你可以只使用 matplotlib 的绘图功能, 这在同时绘制多通道(BGR)的直方图。

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg')
color = ('b','g','r')
# 对一个列表或数组既要遍历索引又要遍历元素时
# 使用内置 enumerrate 函数会有更加直接,优美的做法
#enumerate 会将数组或列表组成一个索引序列。
# 使我们再获取索引和索引内容的时候更加方便
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()

在这里插入图片描述

使用掩模

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

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image.jpg',0)
# create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[0:300, 180:400] = 255
masked_img = cv2.bitwise_and(img,img,mask = mask)
# Calculate histogram with mask and without mask
# Check third argument for 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), plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()

在这里插入图片描述

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值