类 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 个 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)
保存人脸识别器及其模型状态。-
继承自类 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)
使用给定的数据和关联的标签训练人脸识别器。- 参数
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
- 自动生成- 返回
- 自动生成
-
-