类 FaceRecognizer
- java.lang.Object
-
- org.opencv.core.Algorithm
-
- org.opencv.face.FaceRecognizer
-
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::train 在给定图像集(您的人脸数据库!)上对 FaceRecognizer 进行训练。
- 对给定样本图像(即一张人脸)进行预测。图像以 Mat 形式给出。
- 从/向给定 XML 或 YAML 文件加载/保存模型状态。
- 设置/获取标签信息,这些信息以字符串形式存储。字符串标签信息对于保存已识别人员的姓名非常有用。
// 假设我们希望保留 10 个特征脸,阈值为 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();
-
-
构造函数摘要
构造函数 修饰符 构造函数 描述 保护FaceRecognizer(long addr)
-
方法摘要
所有方法 静态方法 实例方法 具体方法 修饰符和类型 方法 描述 static FaceRecognizer__fromPtr__(long addr)protected voidfinalize()java.lang.StringgetLabelInfo(int label)按标签获取字符串信息。MatOfIntgetLabelsByString(java.lang.String str)按字符串获取标签向量。voidpredict(Mat src, int[] label, double[] confidence)预测标签和相关置信度(例如voidpredict_collect(Mat src, PredictCollector collector)如果已实现 - 将所有预测结果发送到收集器,可用于某种自定义结果处理intpredict_label(Mat src)voidread(java.lang.String filename)加载 FaceRecognizer 及其模型状态。voidsetLabelInfo(int label, java.lang.String strInfo)为指定模型的标签设置字符串信息。voidtrain(java.util.List<Mat> src, Mat labels)使用给定数据和相关标签训练 FaceRecognizer。voidupdate(java.util.List<Mat> src, Mat labels)使用给定数据和相关标签更新 FaceRecognizer。voidwrite(java.lang.String filename)保存人脸识别器及其模型状态。-
从类 org.opencv.core.Algorithm 继承的方法
clear, empty, getDefaultName, getNativeObjAddr, save
-
-
-
-
方法详细信息
-
__fromPtr__
public static FaceRecognizer __fromPtr__(long addr)
-
train
public void train(java.util.List<Mat> src, Mat labels)
使用给定数据和相关标签训练 FaceRecognizer。- 参数
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) 模型,并决定保留所有可能的费舍尔脸:// 创建一个新的费舍尔脸模型并保留所有可用的费舍尔脸,// 这是此特定 FaceRecognizer 最常见的用法: // Ptr<FaceRecognizer> model = FisherFaceRecognizer::create();最后,在给定数据集(人脸图像和标签)上对其进行训练:// 这是训练所有可用 cv::FaceRecognizer // 实现的通用接口: // model->train(images, labels);
-
update
public void update(java.util.List<Mat> src, Mat labels)
使用给定数据和相关标签更新 FaceRecognizer。- 参数
src- 训练图像,即您希望学习的人脸。数据必须以 vector<Mat> 的形式给出。labels- 与图像对应的标签必须以 vector<int> 或类型为 CV_32SC1 的 Mat 形式给出。此方法更新一个(可能已训练的)FaceRecognizer,但仅当算法支持时。局部二值模式直方图 (Local Binary Patterns Histograms, 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 的职责。调用者负责维护其希望使用的数据集。
-
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) 中相同的内部循环,但不要尝试获取“最佳”结果,只需使用给定收集器将其重新发送到调用者侧。
-
写
public void write(java.lang.String filename)
保存 FaceRecognizer 及其模型状态。将此模型保存到给定文件名,可以是 XML 或 YAML 格式。- 参数
filename- 用于存储此 FaceRecognizer 的文件名(XML/YAML 格式)。每个 FaceRecognizer 都重写 FaceRecognizer::save(FileStorage& fs) 以保存内部模型状态。FaceRecognizer::save(const String& filename) 将模型状态保存到给定文件名。后缀 const 意味着预测不影响内部模型状态,因此该方法可以在不同线程中安全调用。
-
read
public void read(java.lang.String filename)
加载 FaceRecognizer 及其模型状态。从给定的 XML 或 YAML 文件加载持久化的模型和状态。每个 FaceRecognizer 都必须重写 FaceRecognizer::load(FileStorage& fs) 以启用加载模型状态。FaceRecognizer::load(const String& filename) 反过来会调用 FaceRecognizer::load(FileStorage& fs),以方便保存模型。- 参数
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- 自动生成- 返回
- 自动生成
-
-