gpt4 book ai didi

python - OpenCV Python FAR/FRR中的人脸识别

转载 作者:行者123 更新时间:2023-12-01 06:58:17 25 4
gpt4 key购买 nike

如何在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

  • 因此,该计划如下:
  • 编写函数以读取一些图像数据。
  • cv2.FaceRecognizer包装到scikit-learn估计器中。
  • 使用给定的验证和指标估算cv2.FaceRecognizer的性能。
  • 利润!

  • 正确获取图像数据

    首先,我想在要读取的图像数据上写一些字,因为关于此的问题几乎总是会出现。为简单起见,我在示例中假设图像(文件夹,要识别的人)在文件夹中给出。每人一个文件夹。因此,假设我有一个名为 images的文件夹(数据集),其子文件夹为 person1person2等:
    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

    [...]

    这样的文件夹结构中已经存在的一个公共(public)可用数据集是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中所有图像的大小调整为 100x100像素。:
    [X,y] = read_images("/path/to/some/folder", (100,100))

    scikit-learn中的所有分类器均来自 BaseEstimator,该类应该具有 fitpredict方法。 fit方法获取示例 X和相应标签 y的列表,因此映射到 cv2.FaceRecognizer的train方法很简单。 predict方法还获得了一个样本列表和相应的标签,但是这次我们需要返回每个样本的预测:
    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中找到可用的交叉验证算法:
  • 留一法交叉验证
  • K-folds交叉验证
  • 分层​​K折交叉验证
  • 离开一标签输出交叉验证
  • 具有替代交叉验证的随机采样
  • [...]

  • 为了估计 cv2.FaceRecognizer的识别率,我建议使用分层交叉验证。您可能会问为什么有人需要其他交叉验证方法。想象一下,您想使用算法执行情感识别。如果您的训练集上有与您测试算法的人的影像,将会发生什么?您可能会找到与人最接近的匹配,但找不到情感。在这些情况下,您应该执行与主题无关的交叉验证。

    使用scikit-learn,创建分层k折交叉验证迭代器非常简单:
    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

    现在,我们只需要创建估算器,并将 estimatorXyprecision_scorecv传递给 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, X, y, 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, 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]

    class FaceRecognizerModel(BaseEstimator):

    def __init__(self):
    self.model = cv2.createFisherFaceRecognizer()

    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])]

    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, X, y, score_func=precision_score, 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,因为如您所见,这两个很棒的项目的接口(interface)非常非常容易。

    关于python - OpenCV Python FAR/FRR中的人脸识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12197383/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com