2012-08-09 11 views
6

Zastanawiam użyć OpenCV wdrożenia w Kmeans ponieważ mówi się szybciej ...cv2.kmeans Wykorzystanie w Pythonie

Teraz używam pakiet CV2 i funkcyjnych kmeans,

nie mogę zrozumieć parametry opis w ich odniesienie:

Python: cv2.kmeans(data, K, criteria, attempts, flags[, bestLabels[, centers]]) → retval, bestLabels, centers 
samples – Floating-point matrix of input samples, one row per sample. 
clusterCount – Number of clusters to split the set by. 
labels – Input/output integer array that stores the cluster indices for every sample. 
criteria – The algorithm termination criteria, that is, the maximum number of iterations and/or the desired accuracy. The accuracy is specified as criteria.epsilon. As soon as each of the cluster centers moves by less than criteria.epsilon on some iteration, the algorithm stops. 
attempts – Flag to specify the number of times the algorithm is executed using different initial labelings. The algorithm returns the labels that yield the best compactness (see the last function parameter). 
flags – 
Flag that can take the following values: 
KMEANS_RANDOM_CENTERS Select random initial centers in each attempt. 
KMEANS_PP_CENTERS Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007]. 
KMEANS_USE_INITIAL_LABELS During the first (and possibly the only) attempt, use the user-supplied labels instead of computing them from the initial centers. For the second and further attempts, use the random or semi-random centers. Use one of KMEANS_*_CENTERS flag to specify the exact method. 
centers – Output matrix of the cluster centers, one row per each cluster center. 

co jest argumentem flags[, bestLabels[, centers]]) oznacza? a co z jego: → retval, bestLabels, centers?

Oto mój kod:

import cv, cv2 
import scipy.io 
import numpy 

# read data from .mat file 
mat = scipy.io.loadmat('...') 
keys = mat.keys() 
values = mat.viewvalues() 

data_1 = mat[keys[0]] 
nRows = data_1.shape[1] 
nCols = data_1.shape[0] 
samples = cv.CreateMat(nRows, nCols, cv.CV_32FC1) 
labels = cv.CreateMat(nRows, 1, cv.CV_32SC1) 
centers = cv.CreateMat(nRows, 100, cv.CV_32FC1) 
#centers = numpy. 

for i in range(0, nCols): 
    for j in range(0, nRows): 
     samples[j, i] = data_1[i, j] 


cv2.kmeans(data_1.transpose, 
           100, 
           criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 0.1, 10), 
           attempts=cv2.KMEANS_PP_CENTERS, 
           flags=cv2.KMEANS_PP_CENTERS, 
) 

I napotkać taki błąd:

flags=cv2.KMEANS_PP_CENTERS, 
TypeError: <unknown> is not a numpy array 

Jak należy rozumieć listę parametrów i wykorzystanie cv2.kmeans? Dzięki

Odpowiedz

13

dokumentacja tej funkcji jest prawie niemożliwa do znalezienia. Napisałem poniższy kod Pythona w pośpiechu, ale działa on na moim komputerze. Generuje dwie wielowymiarowe rozkłady Gaussa różnymi metodami, a następnie klasyfikuje je za pomocą cv2.kmeans(). Możesz zapoznać się z this blog post, aby uzyskać pewne pojęcie o parametrach.

import Rękojeść:

import cv 
import cv2 
import numpy as np 
import numpy.random as r 

wygenerować losowe punkty i kształtują je odpowiednio:

samples = cv.CreateMat(50, 2, cv.CV_32FC1) 
random_points = r.multivariate_normal((100,100), np.array([[150,400],[150,150]]), size=(25)) 
random_points_2 = r.multivariate_normal((300,300), np.array([[150,400],[150,150]]), size=(25)) 
samples_list = np.append(random_points, random_points_2).reshape(50,2) 
random_points_list = np.array(samples_list, np.float32) 
samples = cv.fromarray(random_points_list) 

wykreślić punkty przed i po klasyfikacji:

blank_image = np.zeros((400,400,3)) 
blank_image_classified = np.zeros((400,400,3)) 

for point in random_points_list: 
    cv2.circle(blank_image, (int(point[0]),int(point[1])), 1, (0,255,0),-1) 

temp, classified_points, means = cv2.kmeans(data=np.asarray(samples), K=2, bestLabels=None, 
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 1, 10), attempts=1, 
flags=cv2.KMEANS_RANDOM_CENTERS) #Let OpenCV choose random centers for the clusters 

for point, allocation in zip(random_points_list, classified_points): 
    if allocation == 0: 
     color = (255,0,0) 
    elif allocation == 1: 
     color = (0,0,255) 
    cv2.circle(blank_image_classified, (int(point[0]),int(point[1])), 1, color,-1) 

cv2.imshow("Points", blank_image) 
cv2.imshow("Points Classified", blank_image_classified) 
cv2.waitKey() 

Tutaj można zobaczyć oryginalne punkty:

Points before classification

Oto punkty, po tym jak zostały sklasyfikowane: Points after classification

Mam nadzieję, że ta odpowiedź może pomóc, to nie jest kompletny przewodnik do k-średnich, ale będzie przynajmniej pokazać, jak przekazać parametry do OpenCV.

+0

warto zauważyć, że ten przykład wydaje się działać lepiej niż przykładach Pythona przewidzianych w ramach Dokumentacja OpenCV – Chris

1

Problem polega na tym, że Twoja data_1.transpose nie jest tablicą numpy.

Wiązania Pythona OpenCV 2.3.1 i wyższych nie pobierają niczego oprócz numpy array jako parametrów obrazu/macierzy. więc data_1.transpose musi być tablicą numpy.

Generalnie, wszystkie punkty w OpenCV są typu numpy.ndarray

np.

array([[[100., 433.]], 
     [[157., 377.]], 
     . 
     . 
     [[147., 247.]], dtype=float32) 

gdzie każdy element tablicy jest

array([[100., 433.]], dtype=float32) 

i element tej tablicy jest

array([100., 433.], dtype=float32) 
Powiązane problemy