Python 计算机视觉 knn算法和denseSIFT算法原理-图像内容分类-图像识别-手势识别
一、原理
1.K邻近分类法(KNN)
KNN算法是分类算法中最典型最容易实现的算法。
工作原理:存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类对应的关系。输入没有标签的数据后,将新数据中的每个特征与样本集中数据对应的特征进行比较,提取出样本集中特征最相似数据(最近邻)的分类标签。
一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k近邻算法中k的出处,通常k是不大于20的整数。最后选择k个最相似数据中出现次数最多的分类作为新数据的分类。
所以我们可以总结出其算法步骤为:
-
计算测试对象到训练集中每个对象的距离
-
按照距离的远近排序
-
选取与当前测试对象最近的k的训练对象,作为该测试对象的邻居
-
统计这k个邻居的类别频率
-
k个邻居里频率最高的类别,即为测试对象的类别
2.稠密SIFT(Dense SIFT)
Dense SIFT算法,是一种对输入图像进行分块处理,再对每一块进行SIFT运算的特征提取过程。Dense SIFT根据可调的参数大小,来适当满足不同分类任务下对图像的特征表征能力;而传统的SIFT算法则是对整幅图像的处理,得到一系列特征点。
Dense-SIFT在非深度学习的模型中,常常是特征提取的第一步。采样的点提取SIFT描述子后,经过码书投影,投影在同一个码字上的采样点都代表了一组描述子相似的点。不同的码字(相当于直方图的每一个bin)之间,采样点的区分能力是不一样的。我们以下图图1为例,bin2代表的是一块很平坦的区域,于是dense采样时,很多点产生的描述子都会投影在bin2上。而bin1,bin3,bin4分别代表一块特有的区域,仅仅在dense采样到自行车,大提琴和眼睛等部位时,才能够形成类似的描述子。换而言之,bin2的重要性最低,而其他码字的重要性都很高。
通常来讲Dense SIFT更适用于图像分类识别的任务,而传统SIFT更适用于图像检索分割的任务,dense-SIFT在图像检索上的性能不如SIFT检测子的性能好。
二、代码实现
1.KNN算法分类二维数据集
knn分类器
其中K值的选择会影响分类的性能
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=3):
""" 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
votes = {}
for i in range(k):
label = self.labels[ndx[i]]
votes.setdefault(label,0)
votes[label] += 1
return max(votes, key=lambda x: votes.get(x))
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 d