类 FaceRecognizer

  • 直接已知子类
    BasicFaceRecognizer, LBPHFaceRecognizer

    public class FaceRecognizer
    extends Algorithm
    所有面部识别模型的抽象基类 OpenCV 中的所有面部识别模型都派生自抽象基类 FaceRecognizer,它提供对 OpenCV 中所有面部识别算法的统一访问。 ### 描述 我将更详细地解释 FaceRecognizer,因为它乍一看不像一个强大的接口。但是:每个 FaceRecognizer 都是一个 Algorithm,因此您可以轻松地获取/设置所有模型内部结构(如果实现允许)。Algorithm 是一个相对较新的 OpenCV 概念,自 2.4 版本以来可用。我建议您查看其描述。Algorithm 为所有派生类提供以下功能
    • 所谓的“虚拟构造函数”。也就是说,每个 Algorithm 派生类都在程序启动时注册,您可以通过其名称获取已注册算法的列表并创建特定算法的实例(请参见 Algorithm::create)。如果您计划添加自己的算法,最好为您的算法添加一个唯一的开头,以将其与其他算法区分开来。
    • 按名称设置/检索算法参数。如果您使用过 OpenCV highgui 模块的视频捕获功能,您可能熟悉 cv::cvSetCaptureProperty、ocvcvGetCaptureProperty、VideoCapture::set 和 VideoCapture::get。Algorithm 提供类似的方法,其中您使用文本字符串指定参数名称而不是整数 ID。有关详细信息,请参见 Algorithm::set 和 Algorithm::get。
    • 从 XML 或 YAML 文件读取和写入参数。每个 Algorithm 派生类都可以存储其所有参数,然后将其读回。无需每次都重新实现它。
    此外,每个 FaceRecognizer 都支持
    • 训练 使用 FaceRecognizer::train 对给定图像集(您的面部数据库!)训练 FaceRecognizer。
    • 预测 给定样本图像,即面部。图像作为 Mat 给出。
    • 加载/保存 从/到给定的 XML 或 YAML 的模型状态。
    • 设置/获取标签信息,存储为字符串。字符串标签信息对于保存已识别人员的名称很有用。
    注意:当将 FaceRecognizer 接口与 Python 结合使用时,请坚持使用 Python 2。某些底层脚本(如 create_csv)在其他版本(如 Python 3)中无法运行。 设置阈值 +++++++++++++++++++++++ 有时您会遇到想要对预测应用阈值的情况。人脸识别中的一个常见场景是判断面部是否属于训练数据集或是否未知。您可能想知道,为什么 FaceRecognizer 中没有公共 API 来设置预测阈值,但请放心:它受支持。这只是意味着在抽象类中没有通用的方法来提供用于设置/获取*所有可能* FaceRecognizer 算法的阈值的接口。设置阈值的适当位置是在特定 FaceRecognizer 的构造函数中,并且由于每个 FaceRecognizer 都是一个 Algorithm(见上文),因此您可以在运行时获取/设置阈值!以下是如何在创建模型时为 Eigenfaces 方法设置阈值的示例: // 假设我们想要保留 10 个 Eigenfaces 并具有 10.0 的阈值 int num_components = 10; double threshold = 10.0; // 然后,如果您想要一个具有置信度阈值的 cv::FaceRecognizer, // 使用适当的参数创建具体实现: Ptr<FaceRecognizer> model = EigenFaceRecognizer::create(num_components, threshold); 有时不可能训练模型,只是为了试验阈值。由于 Algorithm,可以在运行时设置内部模型阈值。让我们看看如何设置/获取上面创建的 Eigenface 模型的预测: // 下一行从 Eigenfaces 模型读取阈值: double current_threshold = model->getDouble("threshold"); // 这行将阈值设置为 0.0: model->set("threshold", 0.0); 如果您像上面那样将阈值设置为 0.0,则: // Mat img = imread("person1/3.jpg", IMREAD_GRAYSCALE); // 从模型获取预测。注意:我们上面已将阈值设置为 0.0, // 由于距离几乎总是大于 0.0,因此您将得到 -1 作为 // 标签,这表示此面部未知 int predicted_label = model->predict(img); // ... 将产生 -1 作为预测标签,这表明此面部未知。 ### 获取 FaceRecognizer 的名称 由于每个 FaceRecognizer 都是一个 Algorithm,因此您可以使用 Algorithm::name 获取 FaceRecognizer 的名称: // 创建一个 FaceRecognizer: Ptr<FaceRecognizer> model = EigenFaceRecognizer::create(); // 以下是获取其名称的方法: String name = model->name();
    • 构造函数摘要

      构造函数 
      修饰符 构造函数 描述
      protected FaceRecognizer​(long addr)  
    • 方法摘要

      所有方法 静态方法 实例方法 具体方法 
      修饰符和类型 方法 描述
      static FaceRecognizer __fromPtr__​(long addr)  
      protected void finalize()  
      java.lang.String getLabelInfo​(int label)
      按标签获取字符串信息。
      MatOfInt getLabelsByString​(java.lang.String str)
      按字符串获取标签向量。
      void predict​(Mat src, int[] label, double[] confidence)
      预测标签和关联置信度(例如
      void predict_collect​(Mat src, PredictCollector collector)
      如果实现 - 将所有预测结果发送到收集器,以便进行某种自定义结果处理
      int predict_label​(Mat src)  
      void read​(java.lang.String filename)
      加载人脸识别器及其模型状态。
      void setLabelInfo​(int label, java.lang.String strInfo)
      为指定的模型标签设置字符串信息。
      void train​(java.util.List<Mat> src, Mat labels)
      使用给定的数据和关联的标签训练人脸识别器。
      void update​(java.util.List<Mat> src, Mat labels)
      使用给定的数据和关联的标签更新人脸识别器。
      void write​(java.lang.String filename)
      保存人脸识别器及其模型状态。
      • 继承自类 java.lang.Object的方法

        clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • 构造函数详情

      • FaceRecognizer

        protected FaceRecognizer​(long addr)
    • 方法详情

      • __fromPtr__

        public static FaceRecognizer __fromPtr__​(long addr)
      • train

        public void train​(java.util.List<Mat> src,
                          Mat labels)
        使用给定的数据和关联的标签训练人脸识别器。
        参数
        src - 训练图像,即您想要学习的人脸。数据必须以 vector<Mat> 的形式给出。
        labels - 与图像对应的标签必须以 vector<int> 或 CV_32SC1 类型Mat 的形式给出。以下代码片段演示如何在给定图像集上学习 Fisherfaces 模型。图像使用 imread 读取并推入 std::vector<Mat>。每个图像的标签存储在 std::vector<int> 中(您也可以使用 CV_32SC1 类型的 Mat)。将标签视为此图像所属的主题(人),因此相同的主题(人)应该具有相同的标签。对于可用的 FaceRecognizer,您不必注意标签的顺序,只需确保相同的人具有相同的标签: // 存储图像和标签 vector<Mat> images; vector<int> labels; // 使用 CV_32SC1 类型的 Mat // Mat labels(number_of_samples, 1, CV_32SC1); // 第一个人的图像 images.push_back(imread("person0/0.jpg", IMREAD_GRAYSCALE)); labels.push_back(0); images.push_back(imread("person0/1.jpg", IMREAD_GRAYSCALE)); labels.push_back(0); images.push_back(imread("person0/2.jpg", IMREAD_GRAYSCALE)); labels.push_back(0); // 第二个人的图像 images.push_back(imread("person1/0.jpg", IMREAD_GRAYSCALE)); labels.push_back(1); images.push_back(imread("person1/1.jpg", IMREAD_GRAYSCALE)); labels.push_back(1); images.push_back(imread("person1/2.jpg", IMREAD_GRAYSCALE)); labels.push_back(1); 现在您已经读取了一些图像,我们可以创建一个新的 FaceRecognizer。在此示例中,我将创建一个 Fisherfaces 模型并决定保留所有可能的 Fisherfaces: // 创建一个新的 Fisherfaces 模型并保留所有可用的 Fisherfaces, // 这是此特定 FaceRecognizer 最常见的用法: // Ptr<FaceRecognizer> model = FisherFaceRecognizer::create(); 最后,在给定的数据集(人脸图像和标签)上对其进行训练: // 这是训练所有可用 cv::FaceRecognizer // 实现的通用接口: // model->train(images, labels);
      • update

        public void update​(java.util.List<Mat> src,
                           Mat labels)
        使用给定的数据和关联的标签更新人脸识别器。
        参数
        src - 训练图像,即您想要学习的人脸。数据必须以 vector<Mat> 的形式给出。
        labels - 与图像对应的标签必须以 vector<int> 或 CV_32SC1 类型 Mat 的形式给出。此方法更新(可能已训练的)FaceRecognizer,但仅当算法支持时才更新。局部二值模式直方图 (LBPH) 识别器(参见 createLBPHFaceRecognizer)可以更新。对于 Eigenfaces 和 Fisherfaces 方法,这是在算法上不可能的,您必须使用 FaceRecognizer::train 重新估计模型。无论如何,调用 train 会清空现有模型并学习新模型,而 update 不会删除任何模型数据。 // 创建一个新的 LBPH 模型(可以更新)并使用默认参数, // 这是此特定 FaceRecognizer 最常见的用法: // Ptr<FaceRecognizer> model = LBPHFaceRecognizer::create(); // 这是训练所有可用 cv::FaceRecognizer // 实现的通用接口: // model->train(images, labels); // 一些用于保存新图像的容器: vector<Mat> newImages; vector<int> newLabels; // 您应该向容器中添加一些图像: // // ... // // 现在更新模型就像调用一样简单: model->update(newImages,newLabels); // 这将保留旧的模型数据并使用从 newImages 中提取的新特征扩展现有模型! 在不支持更新的 Eigenfaces 模型(参见 EigenFaceRecognizer::create)上调用 update 将抛出类似于以下的错误: OpenCV Error: The function/feature is not implemented (This FaceRecognizer (FaceRecognizer.Eigenfaces) does not support updating, you have to use FaceRecognizer::train to update it.) in update, file /home/philipp/git/opencv/modules/contrib/src/facerec.cpp, line 305 terminate called after throwing an instance of 'cv::Exception' 注意:FaceRecognizer 不会存储您的训练图像,因为这将非常占用内存,并且这不是 FaceRecognizer 的职责。调用者负责维护他想要使用的 dataset。
      • predict_label

        public int predict_label​(Mat src)
      • predict

        public void predict​(Mat src,
                            int[] label,
                            double[] confidence)
        预测给定输入图像的标签和关联置信度(例如,距离)。
        参数
        src - 用于获取预测的样本图像。
        label - 给定图像的预测标签。
        confidence - 预测标签的关联置信度(例如,距离)。后缀 const 表示预测不会影响内部模型状态,因此可以安全地在不同线程中调用该方法。以下示例演示如何从训练好的模型中获取预测: using namespace cv; // 在此处进行初始化(创建 cv::FaceRecognizer 模型) ... // ... // 读取样本图像: Mat img = imread("person1/3.jpg", IMREAD_GRAYSCALE); // 并从 cv::FaceRecognizer 获取预测: int predicted = model->predict(img); 或获取预测和关联置信度(例如,距离): using namespace cv; // 在此处进行初始化(创建 cv::FaceRecognizer 模型) ... // ... Mat img = imread("person1/3.jpg", IMREAD_GRAYSCALE); // 用于预测标签和关联置信度(例如,距离)的一些变量: int predicted_label = -1; double predicted_confidence = 0.0; // 从模型获取预测和关联置信度 model->predict(img, predicted_label, predicted_confidence);
      • predict_collect

        public void predict_collect​(Mat src,
                                    PredictCollector collector)
        • 如果实现 - 将所有预测结果发送到收集器,以便进行某种自定义结果处理
        参数
        src - 用于获取预测的样本图像。
        collector - 接受所有结果的用户定义的收集器对象。要实现此方法,您只需执行与 predict(InputArray src, CV_OUT int &label, CV_OUT double &confidence) 中相同的内部循环,但不要尝试获取“最佳”结果,只需使用给定的收集器将其重新发送到调用方。
      • write

        public void write​(java.lang.String filename)
        保存人脸识别器及其模型状态。将此模型保存到给定的文件名,可以是 XML 或 YAML。
        参数
        filename - 用于存储此 FaceRecognizer 的文件名(XML/YAML)。每个 FaceRecognizer 都重写了 FaceRecognizer::save(FileStorage& fs) 来保存内部模型状态。FaceRecognizer::save(const String& filename) 将模型的状态保存到给定的文件名。const 后缀表示预测不会影响内部模型状态,因此可以在不同的线程中安全地调用此方法。
      • 读取

        public void read​(java.lang.String filename)
        加载 FaceRecognizer 及其模型状态。从给定的 XML 或 YAML 文件加载持久化模型和状态。每个 FaceRecognizer 都必须重写 FaceRecognizer::load(FileStorage& fs) 以启用加载模型状态。FaceRecognizer::load(FileStorage& fs) 又由 FaceRecognizer::load(const String& filename) 调用,以便于保存模型。
        参数
        filename - 自动生成
      • setLabelInfo

        public void setLabelInfo​(int label,
                                 java.lang.String strInfo)
        设置指定模型标签的字符串信息。如果之前已为指定标签设置过字符串信息,则将其替换为提供的值。
        参数
        label - 自动生成
        strInfo - 自动生成
      • getLabelInfo

        public java.lang.String getLabelInfo​(int label)
        按标签获取字符串信息。如果提供了未知的标签 ID 或没有与指定标签 ID 关联的标签信息,则该方法返回空字符串。
        参数
        label - 自动生成
        返回
        自动生成
      • getLabelsByString

        public MatOfInt getLabelsByString​(java.lang.String str)
        按字符串获取标签向量。该函数搜索在关联的字符串信息中包含指定子字符串的标签。
        参数
        str - 自动生成
        返回
        自动生成
      • finalize

        protected void finalize()
                         throws java.lang.Throwable
        重写
        finalize 在类 Algorithm 中
        抛出
        java.lang.Throwable