【问题标题】:cv2.kmeans usage in Pythoncv2.kmeans 在 Python 中的用法
【发布时间】:2012-08-06 19:35:38
【问题描述】:

我正在考虑使用 OpenCV 的 Kmeans 实现,因为它说更快...

现在我正在使用包 cv2 和函数 kmeans,

我无法理解他们参考中的参数描述:

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.

flags[, bestLabels[, centers]]) 的论点是什么意思?那他的呢:→ retval, bestLabels, centers

这是我的代码:

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,
)

我遇到这样的错误:

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

参数列表和cv2.kmeans的用法应该怎么理解?谢谢

【问题讨论】:

    标签: python opencv


    【解决方案1】:

    几乎无法找到有关此功能的文档。我有点匆忙写了下面的 Python 代码,但它可以在我的机器上运行。它生成两个具有不同均值的多元高斯分布,然后使用 cv2.kmeans() 对它们进行分类。您可以参考this blog post 了解参数。

    处理导入:

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

    生成一些随机点并适当地塑造它们:

    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)
    

    绘制分类前后的点:

    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()
    

    这里可以看到原点:

    分类后的点如下:

    我希望这个答案可以帮助你,它不是一个完整的 k-means 指南,但它至少会告诉你如何将参数传递给 OpenCV。

    【讨论】:

    • 值得注意的是,这个示例似乎比 OpenCV 文档中提供的 python 示例效果更好
    • 提供的链接已损坏,仅供参考
    • 已更新。谢谢。
    【解决方案2】:

    这里的问题是你的 data_1.transpose 不是一个 numpy 数组。

    OpenCV 2.3.1 和更高版本的 python 绑定不接受除 numpy array 之外的任何内容作为图像/数组参数。所以,data_1.transpose 必须是一个 numpy 数组。

    通常,OpenCV 中的所有点都是numpy.ndarray 类型

    例如。

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

    数组的每个元素在哪里

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

    并且该数组的元素是

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

    【讨论】:

      猜你喜欢
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 2016-04-23
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      相关资源
      最近更新 更多