Python OpenCV 3.1:KNN 不适用于文档中的示例

Python OpenCV 3.1: KNN not working with the example in docs

我试图让文档中的示例 page 正常工作。

cv2.KNearest() 已替换为 cv2.ml.KNearest_create()

但是,下面的代码片段仍然会导致错误:

#!/usr/bin/python3
import cv2
import numpy as np
import matplotlib.pyplot as plt

# Feature set containing (x,y) values of 25 known/training data
trainData = np.random.randint(0,100,(25,2)).astype(np.float32)

# Labels each one either Red or Blue with numbers 0 and 1
responses = np.random.randint(0,2,(25,1)).astype(np.float32)

# Take Red families and plot them
red = trainData[responses.ravel()==0]
plt.scatter(red[:,0],red[:,1],80,'r','^')

# Take Blue families and plot them
blue = trainData[responses.ravel()==1]
plt.scatter(blue[:,0],blue[:,1],80,'b','s')

newcomer = np.random.randint(0,100,(1,2)).astype(np.float32)
plt.scatter(newcomer[:,0],newcomer[:,1],80,'g','o')

knn = cv2.ml.KNearest_create()
knn.train(trainData,responses)
ret, results, neighbours ,dist = knn.find_nearest(newcomer, 3)

print ("result: ", results,"\n")
print ("neighbours: ", neighbours,"\n")
print ("distance: ", dist)
plt.show()

执行时出现以下错误:

Traceback (most recent call last):
  File "./knn_test.py", line 24, in <module>
    knn.train(trainData,responses)
TypeError: only length-1 arrays can be converted to Python scalars

knn.train() 函数需要:

>>> knn.train.__doc__
'train(trainData[, flags]) -> retval  or  train(samples, layout, responses) -> retval'

我找不到布局定义的示例。为了使其正常工作需要进行哪些更改?

KNN classifier 派生自

StatModel

基地class.

layout

说明符是一个整数,它告诉模型单个样本是占一行还是占一列(参见StatModel::train and ml::SampleTypes)。

由于您有 25 行样本,因此您需要通过

cv2.ml.ROW_SAMPLE

根据 s1h 的回答和 Anupam Sobti 的评论,如果您正在寻找有效的最终代码:

import numpy as np
import cv2

img = cv2.imread('digits.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Split the image to 5000 cells, each 20x20 size
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]

# Make it into a Numpy array. It size will be (50, 100, 20, 20)
x = np.array(cells)

# Now we prepare train_data and test_data.
train = x[:, :50].reshape(-1, 400).astype(np.float32)  # Size = (2500,400)
test = x[:, 50:100].reshape(-1, 400).astype(np.float32)  # Size = (2500,400)

# Create labels for train and test data
k = np.arange(10)
train_labels = np.repeat(k, 250)[:, np.newaxis]
test_labels = train_labels.copy()

# Initiate the kNN, train the data, then test it with test data for k=1
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
ret, result, neighbours, dist = knn.findNearest(test, k=5)

# Now we check the accuracy of classification
# For that, compare the result with test_labels and check which are wrong
matches = result == test_labels
correct = np.count_nonzero(matches)
accuracy = correct * 100.0 / result.size
print("accuracy")
print(accuracy)