在OpenCV-Python中绘制直方图

15

我刚刚尝试使用新的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)

它很好地运作。以下是我得到的直方图结果。

enter image description here


然后我对代码进行了一些修改。

我改变了第六行的代码 b,g,r = cv2.split(img),改为b,g,r = img[:,:,0], img[:,:,1], img[:,:,2](因为它比cv2.split快一点)。

现在的输出与之前不同。下面是输出结果。

enter image description here


我检查了两种代码中的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 谢谢。
1个回答

14

你应该复制这个数组:

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

但是,由于calcHist()函数可以接受通道参数,所以您不需要将图像拆分为三个数组。

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() 接受的 channel 参数是什么意思?它实际上表示什么? - Abid Rahman K
1
你可以调用 cv2.calcHist([img],[CH],None,[256],[0,255]) 来计算图像 img 中通道 CH 的直方图,即 img[:, :, CH]。由于 img[:, :, 0] 中的数据不是连续的,所以你需要复制该数组。 - HYRY
你是指C连续吗?它有什么重要性吗? - Abid Rahman K
最终,确保数组是C连续的任务由OpenCV的Python包装器完成,通过调用np.ascontiguousarray函数实现。这只是我的个人意见。 - letmaik
@user601836 我有同样的问题。 - dorbodwolf
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接