【问题标题】:appending 3d arrays in numpy在 numpy 中附加 3d 数组
【发布时间】:2015-03-31 06:19:03
【问题描述】:

我试图在图像中找到主要颜色,然后确定最主要的颜色。但是我在数据类型方面遇到了麻烦。 我的公式给出了最主要的颜色:

color=[10,10,10] # type=numpy.ndarray ,uint8

但是当我尝试转换它时它给出了断言错误:

color=cv2.cvtColor(color, cv2.COLOR_BGR2HSV) #gives assertion error

cv2.cvtColor 想要作为输入的是:

color_ideal=[[[ 10, 10, 10 ]]]  #type=numpy.ndarray, uint8

为了获得它,我设法像这样操纵颜色:

color=np.uint8(np.atleast_3d(clr).astype(int).reshape(1,1,3))

这似乎可行,但知道我不能将多种颜色附加到 numpy 数组。不知何故,附加维度后,维度减少到 1。我的代码是:

    color=np.uint8([[[]]])

    for item in clt.cluster_centers_:
       color=np.append(color,(np.uint8(np.atleast_3d(item).astype(int).reshape(1,1,3))))
#returns: color=[10,10,10] somehow its dimension is down to 1

我的问题是:

1-如何在不丢失维度的情况下正确附加颜色数据?

2-有没有更简单的方法来处理这个问题?我很惊讶操作自定义颜色像素有多么困难。

完整的代码在这里以防万一:

<!-- language: lang-py -->


    import cv2
    import numpy as np
    from sklearn.cluster import KMeans 

    def find_kmean_colors(img,no_cluster=2):
        clt = KMeans(no_cluster).fit(img)

        return clt
    def initialize(img='people_frontal.jpg'):
        img=cv2.imread('people_frontal_close_body.jpg')
        img=cv2.bilateralFilter(img,9,75,75)
        return img


    img=initialize()

    img_hsv =cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    img_list= img.reshape((img.shape[0] * img_hsv.shape[1], 3))

    clt=(find_kmean_colors(img_list,1))


    color=np.uint8([[[]]])

    for i in clt.cluster_centers_:
        color=np.append(color,(np.uint8(np.atleast_3d(i).astype(int).reshape(1,1,3))))

    #color=np.uint8(np.atleast_3d(clt.cluster_centers_).astype(int).reshape(1,1,3))

    up=cv2.cvtColor(color,cv2.COLOR_BGR2HSV)

【问题讨论】:

  • 重复append 很慢。初始化一个正确大小的空数组,并在正确的位置插入值。或者用所有新东西创建一个,然后concatenate它在正确的维度上。

标签: python opencv numpy multidimensional-array


【解决方案1】:

没有cv2 代码,我在这里猜测形状。但看起来 img 是一个 (n,m,3) 数组。 img_list(m1,3)cltm1 项目的列表,clt.cluster_centers_ 是形状为 (3,) 的 m1 数组的列表。

为了测试,让我们创建一个列表列表(它也可以是一个数组列表):

ctrs=[[10,10,10], [3,5,3], [20,10,10], [0,0,0]]
color = np.array(ctrs,dtype=np.uint8)  # (4,3) array
color = color.reshape(len(ctrs),1,3)

只需将其包裹在np.array 中,然后重塑为 3d。

array([[[10, 10, 10]],
       [[ 3,  5,  3]],
       [[20, 10, 10]],
       [[ 0,  0,  0]]], dtype=uint8)

或者它可以重新整形为 (1,4,3) 或 (2,2,3)。

或者更接近你正在尝试的:

np.concatenate([np.array(i,np.uint8).reshape(1,1,3) for i in ctrs])

您不想在这里使用atleast_3d,因为它将 (N,) 数组重塑为 (1,N,1)(请参阅其文档)。 np.concatenate 在第一个轴上加入,np.array 添加第一个维度然后加入。

您可能可以让append 工作,但它只是逐步连接,速度较慢。一般来说,如果你需要追加,用列表来做,然后在最后转换为数组。


切片后有多种方法可以保留或恢复尺寸。如果color 是 3d 并且您需要第 i 行也为 3d:

color[[i]]
color[i].reshape(1,...)
color[i][np.newaxis,...]

像这样的重塑操作不会显着增加处理时间,所以不要害怕使用它们。

【讨论】:

  • 感谢您的大力帮助。但是,当我尝试使用您创建的数组中的单个颜色时,会出现同样的问题。即: array[1]= [ [ 3, 5, 3] ] 因此仍然缺少一维。我需要得到 array[1]= [ [ [ [ 3, 5, 3 ] ] ]。我需要单独的颜色是 3 维的。
  • array[[1]] 保留维度。
  • 是的,但这个过程是动态的,我不会手动提取颜色。当我有数组并从中提取颜色为 3d 时,我该怎么办?我需要一些可以放入即 for 循环的东西。对于 i in range(len(array)): color=array[ [ i ] ] 。这行得通,你是这个意思吗?它有效,但不知何故它看起来很复杂。顺便说一句,在这个过程的最后,我们需要再次组合各个 3d 颜色。
  • 多出几个括号有什么复杂的?定义一个小函数,根据需要重塑数组并隐藏“复杂性”。
  • 我设法解决了这个问题,非常感谢!最后一件事:在进程结束时,我再次需要一维形式(使用修改后的值),所以我使用'' color=np.squeeze(color,axis=1)''。它有效,但您认为它有效吗?再次非常感谢
猜你喜欢
  • 2015-04-09
  • 2020-03-13
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 2018-01-14
  • 2020-09-02
相关资源
最近更新 更多