vim+python+OpenCV学习五 : 直方图的计算与显示

#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="" />

你可能感兴趣的:(vim+python+OpenCV学习五 : 直方图的计算与显示)