C++ DLIB中用于识别的序列化人脸特征

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(

我正在写一个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(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));
}