C++ DLIB中用于识别的序列化人脸特征
我正在写一个dlib代码来进行1对1的人脸识别 我按照中的代码示例进行了以下操作:C++ DLIB中用于识别的序列化人脸特征,c++,serialization,dlib,C++,Serialization,Dlib,我正在写一个dlib代码来进行1对1的人脸识别 我按照中的代码示例进行了以下操作: std::vector<matrix<rgb_pixel>> faces; for (auto face : detector(img1)) { auto shape = sp(img1, face); matrix<rgb_pixel> face_chip; extract_image_chip(img1, get_face_chip_details(
std::vector<matrix<rgb_pixel>> faces;
for (auto face : detector(img1))
{
auto shape = sp(img1, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
faces.push_back(move(face_chip));
}
我没有保存图像,而是尝试保存特征并加载它们,以减少提取特征所花费的时间。所以我所做的是将第一个for循环移动到另一个函数(类似于注册)并使其如下所示:
std::vector<matrix<rgb_pixel>> faces;
for (auto face : detector(img1))
{
auto shape = sp(img1, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
serialize("personX.dat") <<face_chip;
}
std::向量面;
用于(自动面部:探测器(img1))
{
自动形状=sp(img1,面);
矩阵面片;
提取图像芯片(img1,获取人脸芯片细节(形状,150,0.25),人脸芯片);
序列化(“personX.dat”)face_芯片;
面。推回(移动(面切屑));
从提取img2开始的其余代码保持不变。代码已编译。但在执行过程中,当我达到识别时,我最终出现以下错误:
****************************检测到致命错误****************************
在第216行检测到错误。
在文件/usr/local/include/dlib/dnn/input.h中检测到错误。
函数void dlib::input_rgb_image_size::to_tensor(正向迭代器,正向迭代器,dlib::resize_tensor&)const[带正向迭代器=u gnu_cxx::u normal_迭代器*,std::vector>;长无符号int NR=150ul;长无符号int NC=150ul]中检测到错误
失败的表达式是i->nr()==nr&&i->nc()==nc输入\u rgb\u图像大小::to\u张量()
所有输入图像必须有150行和150列,但我们得到了一个有0行和0列的图像
序列化/反序列化是否有问题?或者是否应该使用其他方法将功能写入文件
完整功能的代码:
try
{
load_image(img1, check_image);
}
catch (...)
{
cout<<"Name: "<<uname<<" doesn't exist"<<endl;
return;
}
else
{
QElapsedTimer timer;
timer.start();
dlib::assign_image(img2, dlib::cv_image<bgr_pixel>(colorImage));
std::vector<matrix<rgb_pixel>> faces;
for (auto face : detector(img1))
{
auto shape = sp(img1, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
faces.push_back(move(face_chip));
// serialize("out.dat")<<face_chip; //used whin i dont need to read image
}
// matrix<rgb_pixel> face_chip; //used whin i dont need to read image
// deserialize("out.dat")>>face_chip; //used whin i dont need to read image
// faces.push_back(move(face_chip)); //used whin i dont need to read image
cout<<"Time to extract features for enroled image: "<<timer.elapsed()<<endl;
timer.restart();
for (auto face : detector(img2))
{
auto shape = sp(img2, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img2, get_face_chip_details(shape, 150, 0.25), face_chip);
faces.push_back(move(face_chip));
}
cout<<"Time to extract features for new image: "<<timer.elapsed()<<endl;
timer.restart();
if (faces.size() < 2)
{
cout<<"No Face"<<endl;
}
else
{
std::vector<matrix<float, 0, 1>> face_descriptors = net(faces);
std::vector<sample_pair> edges;
for (size_t i = 0; i < face_descriptors.size(); ++i)
{
for (size_t j = i; j < face_descriptors.size(); ++j)
{
if (length(face_descriptors[i] - face_descriptors[j]) < threshold)
edges.push_back(sample_pair(i, j));
}
}
std::vector<unsigned long> labels;
const int num_clusters = chinese_whispers(edges, labels);
if (num_clusters == 1)
{
cout<<"Recognized"<<endl;
}
else
{
cout<<"Faces don't match";
}
}
cout<<"Needed time is: "<<timer.elapsed()<<" ms"<<endl;
}
试试看
{
加载图像(img1,检查图像);
}
捕获(…)
{
cout我没有序列化矩阵,而是序列化了输出向量(面)
序列化(“personX.dat”)面;
用于(自动面部:检测器(img2))
{
自动形状=sp(img2,面);
矩阵面片;
提取图像芯片(img2,获取人脸芯片细节(形状,150,0.25),人脸芯片);
面。推回(移动(面切屑));
}
我继续回答问题中提到的问题
我不知道这是否是最好的方法……但它奏效了。你能链接到完整src的要点或其他内容吗?另外,你确定你的图像是好的(即有一张脸,大小合适)?我将发布关于图像的代码作为回复是的,我确信我在图像中有人脸,就好像我没有使用序列化一样。我得到了正确的匹配结果。我将代码添加到问题中。代码中的注释部分是我希望使用的,以避免每次需要匹配时提取图像特征。因此,简而言之我希望提取特征。保存到文件中,然后每当我需要匹配特定的人时,我阅读他的文件,只提取传入图像的特征,从而节省匹配所需的一半时间
load_image(img1, "personX.jpg");
std::vector<matrix<rgb_pixel>> faces;
for (auto face : detector(img1))
{
auto shape = sp(img1, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
serialize("personX.dat") <<face_chip;
}
matrix<rgb_pixel> face_chip;
deserialize("personX.dat")>>face_chip;
faces.push_back(move(face_chip));
try
{
load_image(img1, check_image);
}
catch (...)
{
cout<<"Name: "<<uname<<" doesn't exist"<<endl;
return;
}
else
{
QElapsedTimer timer;
timer.start();
dlib::assign_image(img2, dlib::cv_image<bgr_pixel>(colorImage));
std::vector<matrix<rgb_pixel>> faces;
for (auto face : detector(img1))
{
auto shape = sp(img1, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img1, get_face_chip_details(shape, 150, 0.25), face_chip);
faces.push_back(move(face_chip));
// serialize("out.dat")<<face_chip; //used whin i dont need to read image
}
// matrix<rgb_pixel> face_chip; //used whin i dont need to read image
// deserialize("out.dat")>>face_chip; //used whin i dont need to read image
// faces.push_back(move(face_chip)); //used whin i dont need to read image
cout<<"Time to extract features for enroled image: "<<timer.elapsed()<<endl;
timer.restart();
for (auto face : detector(img2))
{
auto shape = sp(img2, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img2, get_face_chip_details(shape, 150, 0.25), face_chip);
faces.push_back(move(face_chip));
}
cout<<"Time to extract features for new image: "<<timer.elapsed()<<endl;
timer.restart();
if (faces.size() < 2)
{
cout<<"No Face"<<endl;
}
else
{
std::vector<matrix<float, 0, 1>> face_descriptors = net(faces);
std::vector<sample_pair> edges;
for (size_t i = 0; i < face_descriptors.size(); ++i)
{
for (size_t j = i; j < face_descriptors.size(); ++j)
{
if (length(face_descriptors[i] - face_descriptors[j]) < threshold)
edges.push_back(sample_pair(i, j));
}
}
std::vector<unsigned long> labels;
const int num_clusters = chinese_whispers(edges, labels);
if (num_clusters == 1)
{
cout<<"Recognized"<<endl;
}
else
{
cout<<"Faces don't match";
}
}
cout<<"Needed time is: "<<timer.elapsed()<<" ms"<<endl;
}
serialize("personX.dat")<<faces;
std::vector<matrix<rgb_pixel>> faces;
deserialize("out.dat")>>faces;
for (auto face : detector(img2))
{
auto shape = sp(img2, face);
matrix<rgb_pixel> face_chip;
extract_image_chip(img2, get_face_chip_details(shape, 150, 0.25), face_chip);
faces.push_back(move(face_chip));
}