【问题标题】:Colored Histogram HSV 1D彩色直方图 HSV 1D
【发布时间】:2020-06-21 23:14:38
【问题描述】:

我试图从这样的图像创建一个直方图 1d

但我不知道该怎么做。有人可以帮帮我吗?

这是我的 HSV 直方图的简单代码:

from matplotlib import pyplot as plt
import cv2

image = cv2.imread('sample/sample4.jpg')

cv2.cvtColor(image, cv2.COLOR_RGB2HSV)

H, S, V = image[:,:,0],image[:,:,1],image[:,:,2]

plt.figure(figsize=(10,8))
plt.subplot(311)                             #plot in the first cell
plt.subplots_adjust(hspace=.5)
plt.title("Hue")
plt.hist(np.ndarray.flatten(H), bins=180)
plt.subplot(312)                             #plot in the second cell
plt.title("Saturation")
plt.hist(np.ndarray.flatten(S), bins=128)
plt.subplot(313)                             #plot in the third cell
plt.title("Luminosity Value")
plt.hist(np.ndarray.flatten(V), bins=128)
plt.show()

谢谢你的帮助

【问题讨论】:

  • 要实现上图,需要将色调通道聚类成16个bin,确定每个bin的主色,然后计算每个主色出现的频率.计算整个图像的直方图不足以达到您想要的数字,因为您将绘制每个可能的色调值的出现频率。显示的图正在绘制图像中主要可见的内容。即便如此,您还必须考虑饱和度和价值,因此如果没有进一步的上下文,这个问题无法明确回答。

标签: python opencv matplotlib


【解决方案1】:

这是一种使用 Python/OpenCV/Scipy/Matplotpy 的方法,但使用 BGR 颜色。

  • 读取输入
  • 使用 kmeans 将颜色减少到 16 种颜色
  • 获取唯一颜色数组和唯一颜色计数
  • 将每个计数绘制为按颜色着色的条形
  • 保存结果

输入:

import cv2
import numpy as np
from matplotlib import pyplot as plt
from sklearn import cluster

# read image into range 0 to 1
img = cv2.imread('barn.jpg') / 255

# set number of colors
number = 16

# quantize to 16 colors using kmeans
h, w, c = img.shape
img2 = img.reshape(h*w, c)
kmeans_cluster = cluster.KMeans(n_clusters=number)
kmeans_cluster.fit(img2)
cluster_centers = kmeans_cluster.cluster_centers_
cluster_labels = kmeans_cluster.labels_

# need to scale back to range 0-255 and reshape
img3 = cluster_centers[cluster_labels].reshape(h, w, c)*255.0
img3 = img3.astype('uint8')

cv2.imshow('reduced colors',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

# reshape img to 1 column of 3 colors
# -1 means figure out how big it needs to be for that dimension
img4 = img3.reshape(-1,3)

# get the unique colors
colors, counts = np.unique(img4, return_counts=True, axis=0)
print(colors)
print("xxx")
print(counts)
unique = zip(colors,counts)

# function to convert from r,g,b to hex 
def encode_hex(color):
    b=color[0]
    g=color[1]
    r=color[2]
    hex = '#'+str(bytearray([r,g,b]).hex())
    print(hex)
    return hex

# plot each color
fig = plt.figure()
for i, uni in enumerate(unique):
    color = uni[0]
    count = uni[1]
    plt.bar(i, count, color=encode_hex(color))

# show and save plot
plt.show()
fig.savefig('barn_color_historgram.png')
plt.close(fig) 

生成的彩色直方图:

【讨论】:

    【解决方案2】:

    这是 Python/OpenCV 中按 HSV 值排序的替代版本。

    输入:

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    from sklearn import cluster
    
    # read image into range 0 to 1
    img = cv2.imread('barn.jpg') / 255
    
    # set number of colors
    number = 16
    
    # quantize to 16 colors using kmeans
    h, w, c = img.shape
    img2 = img.reshape(h*w, c)
    kmeans_cluster = cluster.KMeans(n_clusters=number)
    kmeans_cluster.fit(img2)
    cluster_centers = kmeans_cluster.cluster_centers_
    cluster_labels = kmeans_cluster.labels_
    
    # need to scale back to range 0-255 and reshape
    img3 = cluster_centers[cluster_labels].reshape(h, w, c)*255.0
    img3 = img3.astype('uint8')
    
    cv2.imshow('reduced colors',img3)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    # reshape img to 1 column of 3 colors
    # -1 means figure out how big it needs to be for that dimension
    img4 = img3.reshape(-1,3)
    
    # get the unique colors
    colors, counts = np.unique(img4, return_counts=True, axis=0)
    
    # compute HSV Value equals max(r,g,b)
    values = []
    for color in colors:
        b=color[0]
        g=color[1]
        r=color[2]
        v=max(b,g,r)
        values.append(v)
    
    # zip colors, counts, values together
    unique = zip(colors,counts,values)
    
    # make list of color, count, value
    ccv_list = []
    for color, count, value in unique:
        ccv_list.append((color, count, value))
        
    # function to define key as third element
    def takeThird(elem):
        return elem[2]
    
    # sort ccv_list by Value (brightness)
    ccv_list.sort(key=takeThird)
    
    # plot each color sorted by increasing Value (brightness)
    # pyplot uses normalized r,g,b in range 0 to 1
    fig = plt.figure()
    length = len(ccv_list)
    for i in range(length):
        item = ccv_list[i]
        color = item[0]
        b = color[0]/255
        g = color[1]/255
        r = color[2]/255
        count = item[1]
        plt.bar(i, count, color=((r,g,b)))
    
    # show and save plot
    plt.show()
    fig.savefig('barn_color_histogram2.png')
    plt.close(fig) 
    

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-13
      • 2014-01-01
      • 2014-12-31
      • 2017-04-26
      • 1970-01-01
      • 2013-01-02
      • 2012-01-13
      • 1970-01-01
      相关资源
      最近更新 更多