Python 3.x 当我希望索引出现时,如何使用numpy.hist
我有一组图像,我想在每个图像的色调值上创建一个直方图。因此,我创建了一个长度为180的数组。如果色调值在图像中,我在每个单元格中添加1。 最后我得到了每个色调值出现的数组,但是当我使用numpy.hist时,y轴是色调值,x轴是出现的。但我想反过来 这是我的密码:Python 3.x 当我希望索引出现时,如何使用numpy.hist,python-3.x,numpy,opencv,histogram,Python 3.x,Numpy,Opencv,Histogram,我有一组图像,我想在每个图像的色调值上创建一个直方图。因此,我创建了一个长度为180的数组。如果色调值在图像中,我在每个单元格中添加1。 最后我得到了每个色调值出现的数组,但是当我使用numpy.hist时,y轴是色调值,x轴是出现的。但我想反过来 这是我的密码: path = 'path' sub_path = 'subpath' sumHueOcc = np.zeros((180, 1), dtype=int) print("sumHue Shape") print(sumHueOcc
path = 'path'
sub_path = 'subpath'
sumHueOcc = np.zeros((180, 1), dtype=int)
print("sumHue Shape")
print(sumHueOcc.shape)
for item in dirs:
fullpath = os.path.join(path,item)
pathos = os.path.join(sub_path,item)
if os.path.isfile(fullpath):
img = np.array(Image.open(fullpath))
f, e = os.path.splitext(pathos)
imgHSV = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
print("Img shape")
print(img.shape)
# want to work with hue only
h, s, v = cv2.split(imgHSV)
# the hue values in one large array
Z = h.reshape((-1, 1))
# convert to np.float32
Z = np.uint32(Z)
# add 1 for each hue value in the image
for z in Z:
sumHueOcc[z] = sumHueOcc[z] + 1
plt.figure(figsize=(9, 8))
plt.subplot(311) # Hue Picture 1
plt.subplots_adjust(hspace=.5)
plt.title("Hue Picture 1")
plt.hist(np.ndarray.flatten(h), bins=180)
plt.subplot(312) # Hue Picture 2
plt.subplots_adjust(hspace=.5)
plt.title("Hue Picture 2")
plt.hist(np.ndarray.flatten(Z), bins=180)
plt.subplot(313) # Hue Picture 2
plt.subplots_adjust(hspace=.5)
plt.title("Sum Occ")
plt.hist(np.ndarray.flatten(sumHueOcc), bins=180)
plt.show()
#First Hue Sum
plt.figure(figsize=(9,8))
plt.title("Sum Hue Occ")
plt.hist(np.ndarray.flatten(sumHueOcc), bins=180)
plt.show()
以下是从半色调更改为全色调的Berriels代码:
print(glob.glob('path with my 4 images'))
# list of paths to the images
image_fname_list = glob.glob('path with my 4 images')
# var to accumulate the histograms
total_hue_hist = np.zeros((359,))
for image_fname in image_fname_list:
# load image
img = cv2.imread(image_fname)
# convert from BGR to HSV
img = np.float32(img)
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
# get the Hue channel
#hue = img_hsv[:, :, 0]
hue, sat, val = cv2.split(img_hsv)
# show histogram
hist, bin_edges = np.histogram(hue, bins=range(360))
total_hue_hist += hist
plt.bar(list(range(359)), hist)
plt.show()
您可以这样做:
导入cv2
将numpy作为np导入
将matplotlib.pyplot作为plt导入
#加载图像
img=cv2.imread('lenna.png')
#从BGR转换为HSV
img\u hsv=cv2.cvt颜色(img,cv2.COLOR\u BGR2HSV)
#获取色调通道
色调=img_hsv[:,:,0]
#显示直方图
hist,bin_边=np。直方图(色调,bins=范围(180))
plt.条(箱边[:-1],历史)
plt.show()
如果不需要绘制直方图值,可以通过以下方式进行:
导入cv2
将matplotlib.pyplot作为plt导入
#加载图像
img=cv2.imread('lenna.png')
#从BGR转换为HSV
img\u hsv=cv2.cvt颜色(img,cv2.COLOR\u BGR2HSV)
#获取色调通道
色调=img_hsv[:,:,0]
#显示直方图
plt.hist(hue.flatte(),bin=range(180))
plt.show()
输入(lenna.png
):
输出:
如果有多个图像,可以执行以下操作:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# list of paths to the images
image_fname_list = ['lenna.png', 'other_image.png', ...]
# var to accumulate the histograms
total_hue_hist = np.zeros((179,))
for image_fname in image_fname_list:
# load image
img = cv2.imread(image_fname)
# convert from BGR to HSV
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# get the Hue channel
hue = img_hsv[:, :, 0]
# show histogram
hist, bin_edges = np.histogram(hue, bins=range(180))
total_hue_hist += hist
plt.bar(list(range(179)), hist)
plt.show()
我使用了另一种方法,将图像放在一个大向量中,并对该向量使用numpy.hist函数。然后我得到所有图像的正确直方图
path = 'path'
sub_path = 'subpath'
sumHueOcc2 = np.zeros((1, 1), dtype=np.uint64)
i=0
for item in dirs:
fullpath = os.path.join(path,item)
pathos = os.path.join(sub_path,item)
if os.path.isfile(fullpath):
img = np.array(Image.open(fullpath))
f, e = os.path.splitext(pathos)
#imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
imgHSV = cv2.cvtColor(img, cv2.COLOR_RGB2HSV) #numpy RGB
# want to work with hue only
h, s, v = cv2.split(imgHSV)
# the hue values in one large array
Z = h.reshape((-1, 1))
# convert to np.float32
Z = np.uint64(Z)
# Huge vector of Images stack
sumHueOcc2 = np.vstack((sumHueOcc2, Z))
if i==0:
sumHueOcc2 = np.delete(sumHueOcc2, (0), axis=0)
i +=1
#Hue Sum for all images
plt.figure(figsize=(9,8))
plt.title("Sum Hue Occ")
plt.hist(np.ndarray.flatten(sumHueOcc2), bins=180)
plt.show()
非常感谢。我尝试了你的解决方案,但它没有显示出应有的结果。数值不在必须的范围内,请参见图3。我的计数数组必须是正确的。我检查了索引38处的数组,它显示的值超过了80.000,但在我的直方图中,该值低于10…@MartinO为什么不将
hist
值相加?如何计算?我打印hist数组的形状及其(10,)。但我使用了另一种方法,将图像堆叠在一个大数组中,然后我可以使用numpy.hist显示所有图像的直方图。这对我来说很有效。@MartinO如果你对我提供的代码的hist
变量求和,你就可以不用叠加图像就可以做到这一点。解决方案是等效的,但您的解决方案具有O(n)
内存占用空间(其中n
是图像的数量),而我的解决方案是O(1)
。最后我用一个示例代码更新了答案。谢谢。我使用了你的代码,但得到了不同的结果。如果我使用我的代码,我得到的色调值35的出现超过800.000。根据您的代码,35的出现率不是最高的,它的出现率超过120.000。色调值34的出现率最高,超过220.000,这与800.000相差甚远,但…这会使您比它应该的多出一个零(sumHueOcc2的初始值),因此您的直方图是错误的(一个值,但它是)。而且,sumHueOcc2
呈线性增长,这可能不是一个好主意。我更新了代码以回应您的评论。@Berriel好的,对我来说这一个值并不重要,因为每个色调值的出现次数超过了10k,但我编辑了代码,所以第一个零条目将被删除。现在向量是正确的。但你的观点绝对正确,谢谢!如果你考虑使用我的代码或者发现它有帮助,也考虑它的投票,这样其他用户就可以很容易地看到一个给定的答案包含一些可以帮助他们的东西。此外,在SO中,如果您提出了一个问题,现在您的问题已经解决,建议您将其中一个答案标记为答案,或者自己回答问题并将其标记为答案。我之所以留下这些评论,是因为上面写着“Martin O是一个新的贡献者。要友善,…)@Berriel谢谢你。我对你的解决方案投了赞成票,但因为我是新手,所以不算数。。。我想标记你的答案,因为你试图帮助我,但你的结果不是必须的结果,因为你的直方图中的值不正确。你知道为什么吗?