简介
在传统的计算机视觉中,我们有两种方法来进行目标检测和识别,第一种就是支持向量机(SVM),第二种就是基于树的目标检测算法(此算法后面会讲到)。
SVM的训练过程常用的方法有两种:词袋方法和隐式支持向量机,它们的区别就是前者可以进行整个场景的识别及分析,而后者主要应用于场景中的具体目标识别,如信号灯、车牌、人脸等。
词袋算法
词袋算法(Bag of Words),也叫Bag of Keypoints,常用于语义分类,也可以用于目标检测与识别。根据该算法的名称,我们就可以得知,该算法的作用就是把相同语义、相似的同类的单词或文件放入一个袋中,然后用关键的词语进行标记。所以说,该算法用到目标检测是非常适合的,因为,每个物体的特征是不同的,就像世界上没有完全一样的两个人。所以对于一些大型的场景,使用该算法比较好,比如在人群中寻找逃犯。
词袋算法的训练过程通常为训练分类器,给定训练集后,算法先将图像转为特征向量,之后对这些向量进行训练。那么之所以归于支持向量机类,就是因为常用的分类器算法是SVM。
在OpenCv中,词袋算法的类为cv2.BOWTrainer(),可用add()方法添加关键点、getDescriptors():返回添加的描述符、getDescriptorsCount():返回添加的描述符数量和cluster():对数据进行聚类分析。当然可以选择其他的聚类算法,如K-means。
接下来就是训练分类器,我们使用一对多的方法,假设目标有十类,就训练是个不同的分类器。以此类推。
由于该算法多用于语义识别,这里就不过多介绍,感兴趣的可以去了解了解。
隐式支持向量机法
隐式支持向量机(Latent SVM)由布朗大学的Felzenszwalb教授提出,最早用于行人检测,后来推广到检测更多其他目标。该算法使用一个滑动窗口,通过窗口将图片分割成片,每一片计算梯度,然后合成梯度直方图,接着将梯度直方图合成一个特征向量,最后用SVM对其进行训练。之所以叫隐式,是因为他不但可以检测整个目标,还可以检测目标的不同组件,例如手,脚,头等。
在OpenCv中,使用DPMDetector类进行目标检测,包括方法create():创建检测器、detect():进行检测、getClassCount():返回分类的数量和getClassNames():获得分类的名称。
话不多说,上代码:
#利用SVM实现手写数字的识别 import cv2 import numpy as np import mlpy #得到图像特征 def getFeatures(filename): #读取图片 img=cv2.imread(filename) #存储特征 vectors=[] w,h,d=img.shape for i in range(w): #x方向特征 xvector=[] for j in range(h): #得到像素颜色 b,g,r=img[i,j] b=255-b g=255-g r=255-r #设置特征值 if b>0 or g>0 or r>0: flag=1 else: flag=0 xvector.append(flag) vectors+=xvector return vectors #读取训练样本和标签 trainimg=[] trainlabel=[] for i in range(10): for j in range(10): #图片名称 filename='train/'+str(i)+'-'+str(j)+'.png' trainimg.append(getFeatures(filename)) trainlabel.append(i) #转换为矩阵 trainimg=np.array(trainimg) trainlabel=np.array(trainlabel) #创建SVM分类器 svm=mlpy.LibSvm(svm_type='c_svc',kernel_type='poly',gamma=5) svm.learn(trainimg,trainlabel) #测试 for i in range(5): testfilename='train/'+str(i)+'-'+str(j)+'-test.png' testing=[] testing.append(getFeatures(testfilename)) #输出结果 print(testfilename+";",svm.pred(testing))
基于书方法的目标检测与识别
基于树的目标检测算法,也叫级联分类器,就是训练多个分类器,将其连接起来。它基于boosting方法,常用于人脸识别。
OpenCv中的级联分类器最早由Michael Jones开发,最初用于人脸识别,后来推广到更多领域,从最初的只支持Harr小波检测发展到支持各种不同的“类Harr”特征。
检测器使用监督方法,利用Adaboost进行拒绝级联。拒绝级联的每个节点设置一个拒绝率,一般设置为50%,每次将拒绝率高于阈值的图片筛选掉,这样通过多次筛选后,剩下的图片或区域就是问哦们需要的目标。
如果节点将正确的目标删了怎么办,其实只要检测率足够高,就可以使删除的目标很少。比如说人脸识别,人脸的占比很小,所以经过一轮的检测,图像中非人脸部分75%都会被删除,这就加快了速度。
在OpenCV中,使用CascadeClassifer对象实现级联分类器,此对象只有一个参数,就是级联器的名字。然后使用其中的detectMultiScale()方法进行图像搜索,此方法的参数为输入图像(img)
输出检测到的物体(objects)、尺寸参数(scaleFactor)、需要的最小邻近目标数量(minNeighbors)、最小面积(minSize)和最大面积(maxSize)。
人脸识别
我们在进行人脸识别前,需要获取人脸的特征,最简单的方法就是使用Harr特征值,其反应了图像的灰度变化情况,例如:眼睛要比脸颊颜色深,鼻梁两侧比鼻梁沈等等。
在OPenCV中已经训练好了模型,下载地址。
#人脸识别 import cv2 #获取训练好的人脸的参数数据,创建分类器 face_cascade=cv2.CascadeClassifier(r'C:\Users\Administrator\AppData\Local\Programs\python\Python310\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml') #读取图片 image=cv2.imread('F:\Image\\test21.jpg') #转为灰度图 gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #探测图片中的人脸,参数根据实际图片而定 faces=face_cascade.detectMultiScale( gray, scaleFactor=1.2, minNeighbors=3, minSize=(10,10) ) #框出人脸 for (x,y,w,h) in faces: cv2.rectangle(image,(x,y),(x+w,y+w),(0,255,0),2) #显示图片 cv2.imshow('Find Faces',image) cv2.waitKey(0)
传统图像总结
传统图像的处理方法就到此结束了,传统图像的处理可以分为三步:第一步,图像颜色空间转化、降噪、美化;第二步,寻找重要特征;第三步,对特征进行训练、分类、识别。
对于这些步骤,虽然看起来很简单,但是对于计算机来说却是非常困难的,效率非常低。所以说,就需要更好的方法。让机器自己去学习,而不是人们去寻找特征。这里就需要深层的神经网络。所以,后面就开始学习深度学习的领域了。