我在这一行遇到了错误:neigh.fit(X, y):ValueError: setting an array element with a sequence.
我检查了fit函数,X是:{array-like, sparse matrix, BallTree, cKDTree}我的X是一个列表的列表,第一个元素是solidity数,第二个元素是humoment列表(7个单元)。如果我更改并只取第一个humoment数以获得一个纯列表的列表,会出现这个错误:query data dimension must match BallTree data dimension.
我的代码:
listafeaturevector = list()path = 'imgknn/'for infile in glob.glob( os.path.join(path, '*.jpg') ): print("current file is: " + infile ) gray = cv2.imread(infile,0) element = cv2.getStructuringElement(cv2.MORPH_CROSS,(6,6)) graydilate = cv2.erode(gray, element) ret,thresh = cv2.threshold(graydilate,127,255,cv2.THRESH_BINARY_INV) imgbnbin = thresh #CONTOURS contours, hierarchy = cv2.findContours(imgbnbin, cv2.RETR_TREE ,cv2.CHAIN_APPROX_SIMPLE) print(len(contours)) for i in range (0, len(contours)): fv = list() #1 feature vector #HUMOMENTS #print("humoments") mom = cv2.moments(contours[i], 1) Humoments = cv2.HuMoments(mom) #print(Humoments) fv.append(Humoments) #query data dimension must match BallTree data dimension #SOLIDITY area = cv2.contourArea(contours[i]) hull = cv2.convexHull(contours[i]) #ha tanti valori hull_area = cv2.contourArea(hull) solidity = float(area)/hull_area fv.append(solidity) #fv.append(elongation) listafeaturevector.append(fv)print("i have done")print(len(listafeaturevector))lenmatrice=len(listafeaturevector)#KNNX = listafeaturevectory = [0,1,2,3]* (lenmatrice/4)from sklearn.neighbors import KNeighborsClassifierneigh = KNeighborsClassifier(n_neighbors=3)neigh.fit(X, y) #ValueError: setting an array element with a sequence.print(neigh.predict([[1.1]]))print(neigh.predict_proba([[0.9]]))
如果我尝试将其转换为numpy数组:
listafv = np.dstack(listafeaturevector)listafv=np.rollaxis(listafv,-1)print(listafv.shape)data = listafv.reshape((lenmatrice, -1))print(data.shape)#KNN
X = data
我得到:setting an array element with a sequence
回答:
几个建议/问题:
Humoments = cv2.HuMoments(mom)
返回值Humoments
的类是什么?是float
还是list
?如果是float
,那就没问题。
for each image file for i in range (0, len(contours)): fv = list() #1 feature vector ... fv.append(Humoments) ... fv.append(solidity) listafeaturevector.append(fv)
上面的代码似乎不正确。在你的问题中,我认为你需要为每张图像构建一个特征向量。所以与图像i
相关的所有内容都应该放入同一个特征向量x_i
中。然后你将所有特征向量组合起来,得到一个特征向量列表X
。然而,你的listafeaturevector
(或X
)出现在最内层的循环中,这显然是不正确的。
其次,你有一个针对contours
中元素数量的循环,你确定每张图像的元素数量相同吗?否则,不同图像的特征数量(|x_i|
)完全不同,这可能会导致错误
setting an array element with a sequence.
第三,你清楚你想如何对图像进行分类吗?不同图像的目标值/标签是什么?我看到你只是用[0,1,2,3]* (lenmatrice/4)
设置标签。你能详细说明你想用这些图像做什么吗?它们包含不同类型的对象吗?它们显示不同的模式吗?这些图像描述不同的主题/颜色吗?如果是的,对于每种不同的类型,你给出一个不同的标签 – 可以是0,1,2或’red’,’white’,’black’(假设你只有3种类型)。标签的值并不重要。重要的是它们有多少个值。我试图理解你情况下labels
的区别。
另一方面,如果你只想检索相似的图像,你不需要使用分类器或为每张图像指定标签。相反,尝试使用NearestNeighbors
。
print(neigh.predict([[1.1]]))print(neigh.predict_proba([[0.9]]))
第四,上面两行测试代码不正确。你需要设置一个X
-like对象才能从分类器中获得预测。也就是说,你需要一个特征向量x
,其结构与你在训练示例中构建的完全相同(所有h,e,s
按相同的顺序排列)。