Python OpenCV 直方图的计算与显示的方法示例


Posted in Python onFebruary 08, 2018

本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图

直方图的背景知识、用途什么的就直接略过去了。这里直接介绍方法。

计算并显示直方图

与C++中一样,在Python中调用的OpenCV直方图计算函数为cv2.calcHist。

cv2.calcHist的原型为:

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

通过一个例子来了解其中的各个参数:

#coding=utf-8 
import cv2 
import numpy as np 
 
image = cv2.imread("D:/histTest.jpg", 0) 
hist = cv2.calcHist([image], 
  [0], #使用的通道 
  None, #没有使用mask 
  [256], #HistSize 
  [0.0,255.0]) #直方图柱的范围

其中第一个参数必须用方括号括起来。

第二个参数是用于计算直方图的通道,这里使用灰度图计算直方图,所以就直接使用第一个通道;

第三个参数是Mask,这里没有使用,所以用None。

第四个参数是histSize,表示这个直方图分成多少份(即多少个直方柱)。第二个例子将绘出直方图,到时候会清楚一点。

第五个参数是表示直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。

最后是两个可选参数,由于直方图作为函数结果返回了,所以第六个hist就没有意义了(待确定)

最后一个accumulate是一个布尔值,用来表示直方图是否叠加。

彩色图像不同通道的直方图

下面来看下彩色图像的直方图处理。以最著名的lena.jpg为例,首先读取并分离各通道:

import cv2   
import numpy as np   
   
img = cv2.imread("D:/lena.jpg")   
b, g, r = cv2.split(img)

接着计算每个通道的直方图,这里将其封装成一个函数:

def calcAndDrawHist(image, color):  
  hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0])  
  minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)  
  histImg = np.zeros([256,256,3], np.uint8)  
  hpt = int(0.9* 256);  
    
  for h in range(256):  
    intensity = int(hist[h]*hpt/maxVal)  
    cv2.line(histImg,(h,256), (h,256-intensity), color)  
      
  return histImg;

这里只是之前代码的简单封装,所以注释就省掉了。

接着在主函数中使用:

if __name__ == '__main__':  
  img = cv2.imread("D:/lena.jpg")  
  b, g, r = cv2.split(img)  
  
  histImgB = calcAndDrawHist(b, [255, 0, 0])  
  histImgG = calcAndDrawHist(g, [0, 255, 0])  
  histImgR = calcAndDrawHist(r, [0, 0, 255])  
    
  cv2.imshow("histImgB", histImgB)  
  cv2.imshow("histImgG", histImgG)  
  cv2.imshow("histImgR", histImgR)  
  cv2.imshow("Img", img)  
  cv2.waitKey(0)  
  cv2.destroyAllWindows()

这样就能得到三个通道的直方图了,如下:

Python OpenCV 直方图的计算与显示的方法示例

更进一步

这样做有点繁琐,参考abid rahman的做法,无需分离通道,用折线来描绘直方图的边界可在一副图中同时绘制三个通道的直方图。方法如下:

#coding=utf-8  
import cv2  
import numpy as np  
     
img = cv2.imread('D:/lena.jpg')  
h = np.zeros((256,256,3)) #创建用于绘制直方图的全0图像  
     
bins = np.arange(256).reshape(256,1) #直方图中各bin的顶点位置  
color = [ (255,0,0),(0,255,0),(0,0,255) ] #BGR三种颜色  
for ch, col in enumerate(color):  
  originHist = cv2.calcHist([img],[ch],None,[256],[0,256])  
  cv2.normalize(originHist, originHist,0,255*0.9,cv2.NORM_MINMAX)  
  hist=np.int32(np.around(originHist))  
  pts = np.column_stack((bins,hist))  
  cv2.polylines(h,[pts],False,col)  
     
h=np.flipud(h)  
     
cv2.imshow('colorhist',h)  
cv2.waitKey(0)

结果如下图所示:

Python OpenCV 直方图的计算与显示的方法示例

代码说明:

这里的for循环是对三个通道遍历一次,每次绘制相应通道的直方图的折线。for循环的第一行是计算对应通道的直方图,经过上面的介绍,应该很容易就能明白。

这里所不同的是没有手动的计算直方图的最大值再乘以一个系数,而是直接调用了OpenCV的归一化函数。该函数将直方图的范围限定在0-255×0.9之间,与之前的一样。下面的hist= np.int32(np.around(originHist))先将生成的原始直方图中的每个元素四舍六入五凑偶取整(cv2.calcHist函数得到的是float32类型的数组),接着将整数部分转成np.int32类型。即61.123先转成61.0,再转成61。注意,这里必须使用np.int32(...)进行转换,numpy的转换函数可以对数组中的每个元素都进行转换,而Python的int(...)只能转换一个元素,如果使用int(...),将导致only length-1 arrays can be converted to Python scalars错误。

下面的pts = np.column_stack((bins,hist))是将直方图中每个bin的值转成相应的坐标。比如hist[0] =3,...,hist[126] = 178,...,hist[255] = 5;而bins的值为[[0],[1],[2]...,[255]]。使用np.column_stack将其组合成[0, 3]、[126, 178]、[255, 5]这样的坐标作为元素组成的数组。

最后使用cv2.polylines函数根据这些点绘制出折线,第三个False参数指出这个折线不需要闭合。第四个参数指定了折线的颜色。

当所有完成后,别忘了用h = np.flipud(h)反转绘制好的直方图,因为绘制时,[0,0]在图像的左上角。这在直方图可视化一节中有说明。

NumPy版的直方图计算

在查阅abid rahman的资料时,发现他用NumPy的直方图计算函数np.histogram也实现了相同的效果。如下:

#coding=utf-8 
import cv2 
import numpy as np 
 
img = cv2.imread('D:/lena.jpg') 
h = np.zeros((300,256,3)) 
bins = np.arange(257) 
bin = bins[0:-1] 
color = [ (255,0,0),(0,255,0),(0,0,255) ] 
 
for ch,col in enumerate(color): 
  item = img[:,:,ch] 
  N,bins = np.histogram(item,bins) 
  v=N.max() 
  N = np.int32(np.around((N*255)/v)) 
  N=N.reshape(256,1) 
  pts = np.column_stack((bin,N)) 
  cv2.polylines(h,[pts],False,col) 
 
h=np.flipud(h) 
 
cv2.imshow('img',h) 
cv2.waitKey(0)

效果图和上面的一个相同。NumPy的histogram函数将在NumPy通用函数这篇博文中介绍,这里就不详细解释了。这里采用的是与一开始相同的比例系数的方法,参考本文的第二节。

另外,通过NumPy和matplotlib可以更方便的绘制出直方图,下面的代码供大家参考,如果有机会,再写的专门介绍matplotlib的文章。

import matplotlib.pyplot as plt 
import numpy as np 
import cv2 
 
img = cv2.imread('D:/lena.jpg') 
bins = np.arange(257) 
 
item = img[:,:,1] 
hist,bins = np.histogram(item,bins) 
width = 0.7*(bins[1]-bins[0]) 
center = (bins[:-1]+bins[1:])/2 
plt.bar(center, hist, align = 'center', width = width) 
plt.show()

Python OpenCV 直方图的计算与显示的方法示例

这里显示的是绿色通道的直方图。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现的石头剪子布代码分享
Aug 22 Python
Python学习之asyncore模块用法实例教程
Sep 29 Python
Python的Tornado框架异步编程入门实例
Apr 24 Python
python定时执行指定函数的方法
May 27 Python
python正则过滤字母、中文、数字及特殊字符方法详解
Feb 11 Python
在python中修改.properties文件的操作
Apr 08 Python
解决python ThreadPoolExecutor 线程池中的异常捕获问题
Apr 08 Python
Python爬虫入门有哪些基础知识点
Jun 02 Python
在CentOS7下安装Python3教程解析
Jul 09 Python
django中cookiecutter的使用教程
Dec 03 Python
pandas 数据类型转换的实现
Dec 29 Python
python和C/C++混合编程之使用ctypes调用 C/C++的dll
Apr 29 Python
python OpenCV学习笔记之绘制直方图的方法
Feb 08 #Python
Python列表推导式与生成器表达式用法示例
Feb 08 #Python
详解python OpenCV学习笔记之直方图均衡化
Feb 08 #Python
python OpenCV学习笔记实现二维直方图
Feb 08 #Python
Python数据分析之双色球基于线性回归算法预测下期中奖结果示例
Feb 08 #Python
Python编程argparse入门浅析
Feb 07 #Python
PyQt5主窗口动态加载Widget实例代码
Feb 07 #Python
You might like
PHP脚本的10个技巧(6)
2006/10/09 PHP
PHP和XSS跨站攻击的防范
2007/04/17 PHP
php事务处理实例详解
2014/07/11 PHP
变量在 PHP7 内部的实现(一)
2015/12/21 PHP
php fread读取文件注意事项
2016/09/24 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
php7性能提升的原因详解
2019/10/13 PHP
php设计模式之抽象工厂模式分析【星际争霸游戏案例】
2020/01/23 PHP
脚本收藏iframe
2006/07/21 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
JS实现关闭当前页而不弹出提示框的方法
2016/06/22 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
微信小程序如何获取用户信息
2018/01/26 Javascript
Vue中v-for的数据分组实例
2018/03/07 Javascript
vue实现在表格里,取每行的id的方法
2018/03/09 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
2019/09/28 Javascript
微信小程序中网络请求缓存的解决方法
2019/12/29 Javascript
简单谈谈python中的多进程
2016/11/06 Python
浅谈python中的正则表达式(re模块)
2017/10/17 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
将python代码和注释分离的方法
2018/04/21 Python
python实现windows壁纸定期更换功能
2019/01/21 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
2020/02/26 Python
超全Python图像处理讲解(多模块实现)
2020/04/13 Python
Pycharm中如何关掉python console
2020/10/27 Python
浏览器实现移动端高性能css3动画(开启gpu加速)
2013/12/23 HTML / CSS
html5 application cache遇到的严重问题
2012/12/26 HTML / CSS
HTML5中的音频和视频媒体播放元素小结
2016/01/29 HTML / CSS
悬挂训练绳:TRX
2017/12/14 全球购物
美国轻奢时尚购物网站:REVOLVE(支持中文)
2020/07/18 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
超市促销实习自我鉴定
2013/09/23 职场文书
房地产销售大学生自我评价分享
2013/11/11 职场文书
个人借款担保书
2014/04/02 职场文书
2014民事授权委托书范本
2014/09/29 职场文书
工程质量保证书
2015/05/09 职场文书