OpenCV Python FAR / FRR中的人脸识别
我如何在OpenCV
Python中进行性能测试来检查;
>获取识别结果所需的时间 我在OpenCV中使用了示例eigenface方法(来自Phillip – https://github.com/bytefish/facerecognition_guide),我只对结果感兴趣.如果有人可以指出我正确的方向/展示例子,那将是很棒的.也许有一些我可以利用的功能? 解决方法
验证OpenCV算法
介绍 首先很抱歉,回复花了这么长时间,但没有空余时间.实际上验证算法是一个非常有趣的话题,并且它真的不那么难.在这篇文章中,我将展示如何验证您的算法(我将采用FaceRecognizer,因为您已经要求它).和我的帖子一样,我将用一个完整的源代码示例来展示它,因为我认为用代码解释东西要容易得多. 所以每当人们告诉我“我的算法表现不好”时,我会问他们: >实际上有什么不好的? 我的希望是,这篇文章将澄清一些混乱,并表明验证算法是多么容易.因为我从试验计算机视觉和机器学习算法中学到的是: >如果没有适当的验证,那就是追逐幽灵.你真的需要数字来谈谈. 此帖子中的所有代码均归BSD许可,因此请随意将其用于您的项目. 验证算法 任何计算机视觉项目最重要的任务之一是获取图像数据.您需要获得与生产中相同的图像数据,这样您在上线时就不会有任何不良体验.一个非常实用的示例:如果您想要识别野外的面部,那么在非常受控的场景中拍摄的图像上验证算法是没有用的.获取尽可能多的数据,因为数据是王道.那是为了数据. 一旦获得了一些数据并且编写了算法,就会对它进行评估.有几种验证策略,但我认为您应该从简单的交叉验证开始,然后从那里开始,有关交叉验证的信息,请参阅: > Wikipedia on Cross-Validation 我们将使用scikit-learn作为一个很好的开源项目,而不是自己完成所有这些: > https://github.com/scikit-learn/ 它有一个非常好的文档和教程来验证算法: > http://scikit-learn.org/stable/tutorial/statistical_inference/index.html 所以计划如下: >编写一个函数来读取一些图像数据. 获取正确的图像数据 首先,我想在要读取的图像数据上写一些单词,因为这个问题几乎总是会出现.为简单起见,我假设在示例中,图像(面部,您要识别的人)在文件夹中给出.每人一个文件夹.所以想象我有一个文件夹(数据集)调用图像,子文件夹是person1,person2等等: philipp@mango:~/facerec/data/images$tree -L 2 | head -n 20 . |-- person1 | |-- 1.jpg | |-- 2.jpg | |-- 3.jpg | |-- 4.jpg |-- person2 | |-- 1.jpg | |-- 2.jpg | |-- 3.jpg | |-- 4.jpg [...] 已经存在于这种文件夹结构中的公共可用数据集之一是AT& T Facedatabase,可从以下位置获得: > http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html 一旦解压缩,它将看起来像这样(在我的文件系统上它被解压缩到/ home / philipp / facerec / data / at /,你的路径是不同的!): philipp@mango:~/facerec/data/at$tree . . |-- README |-- s1 | |-- 1.pgm | |-- 2.pgm [...] | `-- 10.pgm |-- s2 | |-- 1.pgm | |-- 2.pgm [...] | `-- 10.pgm |-- s3 | |-- 1.pgm | |-- 2.pgm [...] | `-- 10.pgm ... 40 directories,401 files 把它放在一起 首先,我们将定义一个方法read_images,用于读取图像数据和标签: import os import sys import cv2 import numpy as np def read_images(path,sz=None): """Reads the images in a given folder,resizes images on the fly if size is given. Args: path: Path to a folder with subfolders representing the subjects (persons). sz: A tuple with the size Resizes Returns: A list [X,y] X: The images,which is a Python list of numpy arrays. y: The corresponding labels (the unique number of the subject,person) in a Python list. """ c = 0 X,y = [],[] for dirname,dirnames,filenames in os.walk(path): for subdirname in dirnames: subject_path = os.path.join(dirname,subdirname) for filename in os.listdir(subject_path): try: im = cv2.imread(os.path.join(subject_path,filename),cv2.IMREAD_GRAYSCALE) # resize to given size (if given) if (sz is not None): im = cv2.resize(im,sz) X.append(np.asarray(im,dtype=np.uint8)) y.append(c) except IOError,(errno,strerror): print "I/O error({0}): {1}".format(errno,strerror) except: print "Unexpected error:",sys.exc_info()[0] raise c = c+1 return [X,y] 然后读取图像数据就像调用一样简单: [X,y] = read_images("/path/to/some/folder") 因为一些算法(例如Eigenfaces,Fisherfaces)要求你的图像大小相等,所以我添加了第二个参数sz.通过传递元组sz,所有图像都会调整大小.因此,以下调用将调整/ path / to / some / folder中的所有图像的大小为100×100像素: [X,y] = read_images("/path/to/some/folder",(100,100)) scikit-learn中的所有分类器都来自BaseEstimator,它应该具有拟合和预测方法. fit方法获取样本X和相应标签y的列表,因此映射到cv2.FaceRecognizer的train方法是微不足道的.预测方法还获得样本和相应标签的列表,但这次我们需要返回每个样本的预测: from sklearn.base import BaseEstimator class FaceRecognizerModel(BaseEstimator): def __init__(self): self.model = cv2.createEigenFaceRecognizer() def fit(self,X,y): self.model.train(X,y) def predict(self,T): return [self.model.predict(T[i]) for i in range(0,T.shape[0])] 然后,您可以在大量验证方法和指标之间进行选择,以测试cv2.FaceRecognizer.您可以在sklearn.cross_validation找到可用的交叉验证算法: > Leave-One-Out交叉验证 为了估计cv2.FaceRecognizer的识别率,我建议使用分层交叉验证.您可能会问为什么有人需要其他交叉验证方法.想象一下,你想用你的算法进行情感识别.如果您的训练集中包含您测试算法的人的图像,会发生什么?您可能会找到与该人最接近的匹配,但不会找到情感.在这些情况下,您应该执行与主题无关的交叉验证. 使用scikit-learn创建分层k-fold交叉验证迭代器非常简单: from sklearn import cross_validation as cval # Then we create a 10-fold cross validation iterator: cv = cval.StratifiedKFold(y,10) 我们可以选择各种各样的指标.现在我只想知道模型的精度,所以我们导入了可调用函数sklearn.metrics.precision_score: from sklearn.metrics import precision_score 现在我们只需要创建我们的估算器并将估算器X,y,precision_score和cv传递给sklearn.cross_validation.cross_val_score,它会计算我们的交叉验证分数: # Now we'll create a classifier,note we wrap it up in the # FaceRecognizerModel we have defined in this file. This is # done,so we can use it in the awesome scikit-learn library: estimator = FaceRecognizerModel() # And getting the precision_scores is then as easy as writing: precision_scores = cval.cross_val_score(estimator,score_func=precision_score,cv=cv) 有大量指标可供选择,请随意选择另一个: > https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/metrics/metrics.py 所以我们把所有这些放在一个脚本中! validation.py # Author: Philipp Wagner <bytefish@gmx.de> # Released to public domain under terms of the BSD Simplified license. # # Redistribution and use in source and binary forms,with or without # modification,are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice,this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice,this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the organization nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # See <http://www.opensource.org/licenses/bsd-license> import os import sys import cv2 import numpy as np from sklearn import cross_validation as cval from sklearn.base import BaseEstimator from sklearn.metrics import precision_score def read_images(path,y] class FaceRecognizerModel(BaseEstimator): def __init__(self): self.model = cv2.createFisherFaceRecognizer() def fit(self,T.shape[0])] if __name__ == "__main__": # You'll need at least some images to perform the validation on: if len(sys.argv) < 2: print "USAGE: facerec_demo.py </path/to/images> [</path/to/store/images/at>]" sys.exit() # Read the images and corresponding labels into X and y. [X,y] = read_images(sys.argv[1]) # Convert labels to 32bit integers. This is a workaround for 64bit machines,# because the labels will truncated else. This is fixed in recent OpenCV # revisions already,I just leave it here for people on older revisions. # # Thanks to Leo Dirac for reporting: y = np.asarray(y,dtype=np.int32) # Then we create a 10-fold cross validation iterator: cv = cval.StratifiedKFold(y,10) # Now we'll create a classifier,note we wrap it up in the # FaceRecognizerModel we have defined in this file. This is # done,so we can use it in the awesome scikit-learn library: estimator = FaceRecognizerModel() # And getting the precision_scores is then as easy as writing: precision_scores = cval.cross_val_score(estimator,cv=cv) # Let's print them: print precision_scores 运行脚本 上面的脚本将打印出Fisherfaces方法的精度分数.您只需要使用image文件夹调用脚本: philipp@mango:~/src/python$python validation.py /home/philipp/facerec/data/at Precision Scores: [ 1. 0.85 0.925 0.9625 1. 0.9625 0.8875 0.93333333 0.9625 0.925 ] 结论 结论是,使用开源项目可以让您的生活变得轻松!示例脚本有很多要增强的功能.您可能想要添加一些日志记录,以查看您所在的折叠.但它是评估您想要的任何指标的开始,只需阅读scikit-learn教程,了解如何操作并使其适应上述脚本. 我鼓励每个人都使用OpenCV Python和scikit-learn,因为你可以看到这两个伟大项目的接口非常非常简单. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |