【问题标题】:Drawing Histogram in OpenCV-Python在 OpenCV-Python 中绘制直方图
【发布时间】:2012-03-12 12:47:07
【问题描述】:

我只是尝试使用新的 OpenCV Python 接口 (cv2) 绘制直方图。

下面是我试过的代码:

import cv2
import numpy as np
import time

img = cv2.imread('zzz.jpg')
h = np.zeros((300,256,3))
b,g,r = cv2.split(img)
bins = np.arange(256).reshape(256,1)
color = [ (255,0,0),(0,255,0),(0,0,255) ]

for item,col in zip([b,g,r],color):
    hist_item = cv2.calcHist([item],[0],None,[256],[0,255])
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX)
    hist=np.int32(np.around(hist_item))
    pts = np.column_stack((bins,hist))
    cv2.polylines(h,[pts],False,col)

h=np.flipud(h)

cv2.imshow('colorhist',h)
cv2.waitKey(0)

而且效果很好。下面是我得到的结果直方图。


然后我稍微修改了代码。

ie 将代码b,g,r = cv2.split(img) 中的第六行更改为b,g,r = img[:,:,0], img[:,:,1], img[:,:,2](因为它比cv2.split 运行得快一点)。

现在输出有所不同。下面是输出。


我从两个代码中检查了b,g,r 的值。他们是一样的。

区别在于cv2.calcHist 的输出。 hist_item 的结果在这两种情况下都不同。

问题

它是如何发生的?为什么输入相同时cv2.calcHist的结果不一样?

编辑

我尝试了不同的代码。现在,我的第一个代码的 numpy 版本。

import cv2
import numpy as np

img = cv2.imread('zzz.jpg')
h = np.zeros((300,256,3))
b,g,r = img[:,:,0],img[:,:,1],img[:,:,2]
bins = np.arange(257)
bin = bins[0:-1]
color = [ (255,0,0),(0,255,0),(0,0,255) ]

for item,col in zip([b,g,r],color):
    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,2)

h=np.flipud(h)

cv2.imshow('img',h)
cv2.waitKey(0)

并且输出与第一个相同。

你可以在这里得到我的原图:zzz.jpg

谢谢。

【问题讨论】:

    标签: python opencv numpy computer-vision histogram


    【解决方案1】:

    你应该复制数组:

    b,g,r = img[:,:,0].copy(), img[:,:,1].copy(), img[:,:,2].copy()
    

    但是,由于 calcHist() 可以接受 channels 参数,你不需要将你的 img 拆分为三个数组。

    import cv2
    import numpy as np
    
    img = cv2.imread('zzzyj.jpg')
    h = np.zeros((300,256,3))
    
    bins = np.arange(256).reshape(256,1)
    color = [ (255,0,0),(0,255,0),(0,0,255) ]
    
    for ch, col in enumerate(color):
        hist_item = cv2.calcHist([img],[ch],None,[256],[0,255])
        cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX)
        hist=np.int32(np.around(hist_item))
        pts = np.column_stack((bins,hist))
        cv2.polylines(h,[pts],False,col)
    
    h=np.flipud(h)
    
    cv2.imshow('colorhist',h)
    cv2.waitKey(0)
    

    【讨论】:

    • copy需要什么? calcHist() 接受通道参数是什么意思?它实际上表示什么?
    • 可以调用cv2.calcHist([img],[CH],None,[256],[0,255])计算img的通道CH直方图,即img[:, :, CH]。您需要复制数组,因为 img[:, :, 0] 中的数据不连续。
    • 你的意思是 c_contiguous?它有什么意义?
    • numpy 在操作数组方面更有效,在 cv2 中使用。 python split 运算符不会将所有数据保存在一起。复制操作员整齐地收集它们。
    • 但是是我还是图片尺寸不是300 * 256?
    猜你喜欢
    • 1970-01-01
    • 2015-05-29
    • 2015-11-11
    • 2011-08-21
    • 1970-01-01
    • 2023-03-03
    • 2018-05-23
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多