#coding=utf-8 import cv2 import numpy as np ''' 在Python中调用的OpenCV直方图计算函数为cv2.calcHist cv2.calcHist(images, channels, mask, histSize, ranges[], hist[, accumulate ]) #返回hist 其中第一个参数必须用方括号括起来。表示可以有几幅图像一起做一个直方图 第二个参数是用于计算直方图的通道,这里使用灰度图计算直方图,所以就直接使用第一个通道; 第三个参数是Mask,这里没有使用,所以用None。 第四个参数是histSize,表示这个直方图分成多少份(即多少个直方柱)。第二个例子将绘出直方图,到时候会清楚一点。 第五个参数是表示直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。 最后是两个可选参数,由于直方图作为函数结果返回了,所以第六个hist就没有意义了(待确定) 最后一个accumulate是一个布尔值,用来表示直方图是否叠加。 ''' def calcAndDrawHist(image,color): hist=cv2.calcHist([image], [0],#使用的通道 None,#没有使用mask [256],#HistSize [0.0,255.0])#直方图柱的范围 minVal,maxVal,minLoc,maxLoc=cv2.minMaxLoc(hist) #location位置,直方图的最大值和最小值以及其横坐标值 histImg=np.zeros([256,256,3],np.uint8) hpt=int(0.9*256) #cv2.line(img,(0,0),(511,511),(255,0,0),5) ,图像,起点,终点,颜色,线条宽度 for h in range(256): intensity=int(hist[h]*hpt/maxVal) #intensity强度,hist[h]/maxVa * hpt 这样更清楚,保证最大值占255的九成 cv2.line(histImg,#新建的一副空白图片 (h,256), #起点 (h,256-intensity),终点 color)#画线用的颜色 return histImg if __name__=='__main__': img=cv2.imread("test.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()
</pre><pre code_snippet_id="1594954" snippet_file_name="blog_20160302_4_6321083" name="code" class="python">
<img src="http://img.blog.csdn.net/20160302184807332?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
</pre><pre code_snippet_id="1594954" snippet_file_name="blog_20160302_4_6321083" name="code" class="python">#coding=utf-8 import cv2 import numpy as np ''' 参考abid rahman的做法,无需分离通道,用折线来描绘直方图的边界可在一副图中同时绘制 三个通道的直方图。方法如下: ''' img=cv2.imread("test.jpg") h=np.zeros((256,256,3)) 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])#这里的ch是mark把线给染色 cv2.normalize(originHist,originHist,0,255*0.9,cv2.NORM_MINMAX)#归一化,直方图的范围限定在0-255×0.9之间按最大最小值归一化,和之前的一样 hist=np.int32(np.around(originHist))#先将生成的原始直方图中的每个元素四舍六入五凑偶取整 #(cv2.calcHist函数得到的是float32类型的数组),接着将整数部分转成np.int32类型 #是将直方图中每个bin的值转成相应的坐标 ''' >>> np.vstack(([1,2,3],[4,5,6])) array([[1, 2, 3], [4, 5, 6]]) >>> np.column_stack(([1,2,3],[4,5,6])) array([[1, 4], [2, 5], [3, 6]]) >>> np.hstack(([1,2,3],[4,5,6])) array([1, 2, 3, 4, 5, 6]) ''' pts=np.column_stack((bins,hist))#弄成一个坐标系 cv2.polylines(h,[pts],False,col)#1-256,第二坐标#第三个False参数指出这个折线不需要闭合,第四个参数指定了折线的颜色。 h=np.flipud(h)#翻转每列,因为绘制时,[0,0]在图像的左上角。这在直方图可视化一节中有说明。 cv2.imshow("colorHist",h) cv2.waitKey(0) cv2.destroyAllWindows()
<img src="http://img.blog.csdn.net/20160302184906705?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
#coding=utf-8 import cv2 import numpy as np ''' 用NumPy的直方图计算函数np.histogram也实现了相同的效果。 ''' img=cv2.imread("test.jpg") h=np.zeros((300,256,3)) bins=np.arange(257)#直方图中各bin的顶点位置 #str[a:b]表示截取字符串的a开始的位置,b表示结束位置 #b是负数,表示去出后几位 bin=bins[0:-1] color = [(255,0,0),(0,255,0),(0,0,255)] #BGR三种颜色 for ch,col in enumerate(color): item=img[:,:,ch]#表明第几维矩阵,可以用色彩作文引用的标志红黄蓝代替123 N,bins=np.histogram(item,bins)#把图像的一个通道放在bins里面,成为一系列的值 v=N.max()#求取最大值 N=np.int32(np.around((N*255)/v))#把数组标准化,保证高度不超过255 N=N.reshape(256,1) pts=np.column_stack((bin,N)) cv2.polylines(h,[pts],False,col) h=np.flipud(h) cv2.imshow("colorHist",h) cv2.waitKey(0) cv2.dest
<img src="http://img.blog.csdn.net/20160303100016809?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
import cv2 import numpy as np import matplotlib.pyplot as plt ''' 用NumPy的直方图计算函数np.histogram也实现了相同的效果。 ''' img=cv2.imread("test.jpg") bins=np.arange(257)#直方图中各bin的顶点位置 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()
<img src="http://img.blog.csdn.net/20160303102803381?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />