2015-02-01 3 views
1

Я пытаюсь найти доминирующие цвета на изображении, а затем перехватить наиболее доминирующий. Однако у меня возникают проблемы с типами данных. Моя формула дает наиболее доминирующий цвет, как:Добавление трехмерных массивов в numpy

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 array.Somehow, после добавления размер уменьшается до 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) 
+0

Повторяющееся 'append' медленно. Сначала введите пустой массив нужного размера и вставьте значения в нужные места. Или создайте его со всем новым материалом и «соедините» его в правильном измерении. – hpaulj

ответ

0

Без cv2 кода, я предполагаю, о формах здесь. Но выглядит как img является массив (n,m,3). img_list - (m1,3) и clt в виде списка m1 элементов, а clt.cluster_centers_ - список массивов m1 формы (3,).

Ради тест позволяет составить список списков (он точно так же может быть список массивов):

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 присоединяется к 1-й оси, где np.array добавляет 1-е измерение и затем присоединяется.

Возможно, вы можете получить append, но он просто выполняет пошаговую конкатенацию, которая медленнее. В общем, если вам нужно добавить, сделайте это со списками, а затем конвертируйте в массив в конце.

Существуют различные способы сохранения или восстановления размеров после нарезки.Если color является 3d и вам потребуется ряд i-го также в 3d:

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

Изменение формы операции, как это не значительно увеличить время обработки, так что не бойтесь использовать их.

+0

спасибо за большую помощь. Однако такая же проблема возникает, когда я пытаюсь использовать индивидуальный цвет из созданного массива. т.е.: array [1] = [[3, 5, 3]], поэтому 1 размер все еще отсутствует. Мне нужно получить массив [1] = [[[3, 5, 3]]]. Мне нужно, чтобы отдельные цвета были трехмерными. – talha

+0

'array [[1]]' сохраняет размерность. – hpaulj

+0

Да, но процесс динамический, и я не извлекаю цвет вручную. Что мне делать, когда у меня есть массив и извлекать из него цвета как 3d? Мне нужно что-то, что я могу сделать, например, для цикла. для i в диапазоне (len (массив)): color = array [[i]]. Это работает, ты имеешь в виду? он работает, но как-то это выглядит сложным. Кстати, в конце этого процесса нам нужно снова объединить отдельные 3D-цвета. – talha

Смежные вопросы