# Python计算机视觉 图像内容分类

1.K邻近分类法（KNN）
2.用稠密SIFT作为图像特征
3.手势识别

## 一、K邻近分类法（KNN）

from numpy import *

class KnnClassifier(object):

def __init__(self,labels,samples):
""" Initialize classifier with training data. """

self.labels = labels
self.samples = samples

def classify(self,point,k=7):
""" Classify a point against k nearest
in the training data, return label. """

# compute distance to all training points
dist = array([L2dist(point,s) for s in self.samples])

# sort them
ndx = dist.argsort()

# use dictionary to store the k nearest
for i in range(k):
label = self.labels[ndx[i]]

def L2dist(p1,p2):
return sqrt( sum( (p1-p2)**2) )

def L1dist(v1,v2):
return sum(abs(v1-v2))


# -*- coding: utf-8 -*-
from numpy.random import randn
import pickle
from pylab import *

# create sample data of 2D points
n = 200
# two normal distributions
class_1 = 0.6 * randn(n,2)
class_2 = 1.2 * randn(n,2) + array([5,1])
labels = hstack((ones(n),-ones(n)))
# save with Pickle
#with open('points_normal.pkl', 'w') as f:
with open('points_normal_test.pkl', 'wb') as f:
pickle.dump(class_1,f)
pickle.dump(class_2,f)
pickle.dump(labels,f)
# normal distribution and ring around it
print ("save OK!")
class_1 = 0.6 * randn(n,2)
r = 0.8 * randn(n,1) + 5
angle = 2*pi * randn(n,1)
class_2 = hstack((r*cos(angle),r*sin(angle)))
labels = hstack((ones(n),-ones(n)))
# save with Pickle
#with open('points_ring.pkl', 'w') as f:
with open('points_ring_test.pkl', 'wb') as f:
pickle.dump(class_1,f)
pickle.dump(class_2,f)
pickle.dump(labels,f)

print ("save OK!")


# -*- coding: utf-8 -*-
import pickle
from pylab import *
from PCV.classifiers import knn
from PCV.tools import imtools

pklist=['points_normal.pkl','points_ring.pkl']

figure()

# load 2D points using Pickle
for i, pklfile in enumerate(pklist):
with open(pklfile, 'rb') as f:
# load test data using Pickle
with open(pklfile[:-4]+'_test.pkl', 'rb') as f:

model = knn.KnnClassifier(labels,vstack((class_1,class_2)))
# test on the first point
print (model.classify(class_1[0]))

#define function for plotting
def classify(x,y,model=model):
return array([model.classify([xx,yy]) for (xx,yy) in zip(x,y)])

# lot the classification boundary
subplot(1,2,i+1)
imtools.plot_2D_boundary([-6,6,-6,6],[class_1,class_2],classify,[1,-1])
titlename=pklfile[:-4]
title(titlename)
show()


PS:k值理论上要取奇数，因为原理是要从最近的k个点里面看看两个类的点分别有几个，偶数的话万一碰到两边数量一样的就没有办法分类

1.k=3，n=200

2.k=5，n=200

3.k=9，n=200

1.k值越大运行速度越慢
2.k值越大，分类的不确定越大，多次运行以后才会没出现错误点

## 二、用稠密SIFT作为图像特征

（以下参考： https://blog.csdn.net/breeze5428/article/details/25055291
dense SIFT与做特征匹配所用到的SIFT的不同点。dense SIFT是提取我们感兴趣的patches中的每个位置的SIFT特征。而通常做特征匹配的SIFT算法只是得到感兴趣区域或者图像上若干个稳定的关键点的SIFT特征。

# -*- coding: utf-8 -*-
from PCV.localdescriptors import sift, dsift
from pylab import  *
from PIL import Image

dsift.process_image_dsift('gesture/zhongshan.jpg','zhongshan.dsift',90,40,True)
im = array(Image.open('gesture/zhongshan.jpg'))
sift.plot_features(im,l,True)
title('dense SIFT')
show()


PS： 记得在 dsift.py（在PCV.localdescriptors中的文件）中把路径改成自己的sift.exe所在路径。

## 三、手势识别

# -*- coding: utf-8 -*-
import os
from PCV.localdescriptors import sift, dsift
from pylab import  *
from PIL import Image

imlist=['gesture/train1/A-uniform01.JPG','gesture/train1/B-uniform01.JPG',
'gesture/train1/C-uniform01.JPG','gesture/train1/D-uniform01.JPG',
'gesture/train1/E-uniform01.JPG','gesture/train1/F-uniform01.JPG']

figure()
for i, im in enumerate(imlist):
print (im)
dsift.process_image_dsift(im,im[:-3]+'dsift',50,20,True)
dirpath, filename=os.path.split(im)
im = array(Image.open(im))
#显示手势含义title
titlename=filename[:-14]
subplot(2,3,i+1)
sift.plot_features(im,l,True)
title(titlename)
show()


train1是训练集，理论上越多越好。
test1是测试集，主要测试各种各样的手势。

# -*- coding: utf-8 -*-
from PCV.localdescriptors import dsift
import os
from PCV.localdescriptors import sift
from pylab import *
from PCV.classifiers import knn

def get_imagelist(path):
"""    Returns a list of filenames for
all jpg images in a directory. """

return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')]

# create list of all files ending in .dsift
featlist = [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.dsift')]
features = []
for featfile in featlist:
features.append(d.flatten())
features = array(features)
# create labels
labels = [featfile.split('/')[-1][0] for featfile in featlist]
return features,array(labels)

def print_confusion(res,labels,classnames):
n = len(classnames)
# confusion matrix
class_ind = dict([(classnames[i],i) for i in range(n)])
confuse = zeros((n,n))
for i in range(len(test_labels)):
confuse[class_ind[res[i]],class_ind[test_labels[i]]] += 1
print ('Confusion matrix for')
print (classnames)
print (confuse)

filelist_train = get_imagelist('gesture/train2')
filelist_test = get_imagelist('gesture/test2')
imlist=filelist_train+filelist_test

# process images at fixed size (50,50)
for filename in imlist:
featfile = filename[:-3]+'dsift'
dsift.process_image_dsift(filename,featfile,10,5,resize=(50,50))

classnames = unique(labels)

# test kNN
k = 1
knn_classifier = knn.KnnClassifier(labels,features)
res = array([knn_classifier.classify(test_features[i],k) for i in
range(len(test_labels))])
# accuracy
acc = sum(1.0*(res==test_labels)) / len(test_labels)
print ('Accuracy:', acc)

print_confusion(res,test_labels,classnames)


1.输入C类手势，识别为E

2.输入D类手势，识别为E

3.输入E类手势，识别为E

4.输入A类手势，识别为C

5.输入为A类手势，识别为A

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客