我写了一个程序,旨在根据相似性对图像进行分类:
for i in g:
fulFi = i
tiva = []
tivb = []
a = cv2.imread(i)
b = cv2.resize(a, (500, 500))
img2 = flatten_image(b)
tivb.append(img2)
cb = np.array(tivb)
iab = trueArray(cb)
print "Image: " + (str(i)).split("/")[-1]
print "Image Size " + str(len(iab))
print "Image Data: " + str(iab) + "n"
pca = RandomizedPCA(n_components=2)
X = pca.fit_transform(iab)
Xy = pca.transform(X)
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X, Xy.ravel())
def aip(img):
a = cv2.imread(img)
b = cv2.resize(a, (500, 500))
tivb = []
r = flatten_image(b)
tivb.append(r)
o = np.array(tivb)
l = trueArray(o)
print "Test Image: " + (str(img)).split("/")[-1]
print "Test Image Size " + str(len(l))
print "Test Image Data: " + str(l) + "n"
return l
testIm = aip(sys.argv[2])
b = pca.fit_transform(testIm)
print "KNN Prediction: " + str(knn.predict(b))
虽然它功能完美,但它有一个错误:无论使用什么图像,它都给了我完全相同的值:
Image: 150119131035-green-bay-seattle-nfl-1024x576.jpg
Image Size 750000
Image Data: [255 242 242 ..., 148 204 191]
Test Image: agun.jpg
Test Image Size 750000
Test Image Data: [216 255 253 ..., 205 225 242]
KNN Prediction: [-255.]
和
Image: 150119131035-green-bay-seattle-nfl-1024x576.jpg
Image Size 750000
Image Data: [255 242 242 ..., 148 204 191]
Test Image: bliss.jpg
Test Image Size 750000
Test Image Data: [243 240 232 ..., 13 69 48]
KNN Prediction: [-255.]
无论使用何种图像,KNN预测始终为255。经过进一步调查,A发现问题出在我的PCA上:出于某种原因,它取了一个值为750000的数组,却返回了一个只有一个值的数组:
pca = RandomizedPCA(n_components=2)
X = pca.fit_transform(iab)
Xy = pca.transform(X)
print "Iab: " + str(iab)
print "Iab Type: " + str(type(iab))
print "Iab length: " + str(len(iab))
print "X Type: " + str(type(X))
print "X length: " + str(len(X))
print "X: " + str(X)
print "Xy Type: " + str(type(Xy))
print "Xy Length: " + str(len(X))
print "Xy: " + str(Xy)
给出:
Image: 150119131035-green-bay-seattle-nfl-1024x576.jpg
Image Size 750000
Image Data: [255 242 242 ..., 148 204 191]
Iab: [255 242 242 ..., 148 204 191]
Iab Type: <type 'numpy.ndarray'>
Iab length: 750000
X Type: <type 'numpy.ndarray'>
X length: 1
X: [[ 0.]]
Xy Type: <type 'numpy.ndarray'>
Xy Length: 1
Xy: [[-255.]]
我的问题是为什么?X和Xy都应该有数百个值,而不仅仅是一个。我遵循的教程没有解释,文档只说transform和fit_transform都需要相同的数组格式。我该如何处理?
如果n_components=2
,RandomizedPCA
最多只保留2个组件(请参阅此处的文档)。尝试增加此值以允许选择更多组件;这应该能解决你的问题。
您对X = pca.fit_transform(iab)
和Xy = pca.transform(X)
所做的操作是错误的。
- 您正在丢失两个图像的
iab
变量。你需要两个图像的扁平阵列,在for循环之外。然而在第一次迭代之后,第二次迭代将覆盖iab
数组 - 即使单独保存两个阵列,例如
iab[0]
和iab[1]
,也需要对这两个阵列执行PCA,并使用沿变换轴表示的两个图像。不过,您需要决定使用什么来学习转换
这是示例代码:
# First initialize the PCA with desired components
pca = RandomizedPCA(n_components=2)
# Next you need to fit data to learn the transformations
pca.fit(np.vstack(iab[0].shape(1, len(iab[0]), iab[1].shape(1, len(iab[1])))
# Finally you apply this learned transformation on input data
X[0] = pca.transform(iab[0])
X[1] = pca.transform(iab[1])
你基本上是在矩阵上学习主成分分析。行表示每个图像。你想做的是试图识别图像中哪些像素最能描述图像。为此,您需要输入许多图像,并找出哪些像素比其他像素更能区分它们。在使用拟合的方式中,您只需在1D列表中输入100个值,这实际上意味着,您有一个值代表每个图像,而您有100个图像。
同样在您的案例中,您将fit()
和transform()
组合在一起,这是一个有效的用例,前提是您了解它所代表的内容。不管怎样,您错过了第二个图像的转换。
如果你想了解更多关于PCA的工作原理,你可以阅读这个答案。
最后,您无法在1个训练样本和1个测试样本上学习KNN分类器!学习算法是指从大量的输入中学习。
你似乎只需要两者之间的基本距离。你需要选择一个距离度量。如果你选择使用欧几里得距离(也称为L2范数),那么这里有它的代码:
dist = numpy.linalg.norm(X[0]-X[1])
你也可以这样做:
from scipy.spatial import distance
dist = distance.euclidean(X[0], X[1])
在任何情况下,再次转换转换后的数据都没有意义,就像使用Xy = pca.transform(X)
一样。这不会给你一个目标。
当你有100张图像时,你只能应用KNN之类的分类,其中50张显示"树",其余50张显示一辆"车"。一旦你训练了模型,你就可以预测一个新的图像是一棵树还是一辆车。