• SeetaFaceEngine系列2:Face Alignment编译和使用


    前面一篇写了编译人脸检测部分,现在就介绍下人脸配准部分,SeetaFace的Face Alignment通过人脸的五个关键点来配准人脸,也就是双眼、鼻尖、两个嘴角。

    这部分的编译也和上一篇一样,步骤如下:

    1、创建空的DLL工程:

    2、修改配置器:

    3、添加include:

    这里要注意,因为人脸配准需要先检测人脸,会用到前面配置好的人脸检测,所以要加上其头文件;

    4、添加Lib文件路径和依赖项

    5、修改预处理器:

    6、打开OpenMP:

    7、添加源文件到工程:

    image.png

    一样,先将SeetaFaceEngineFaceDetectionsrc下的所有文件和文件夹(test除外)都复制到工程目录下,并将全部文件添加到工程中。

    8、编译工程(Release的步骤也是一样的)

    9、使用Face Alignment

    这里使用的是FaceAlignmentsrc est下的face_alignment_test.cpp,需要根据自己的路径修改模型和数据的路径

    int testFaceAlignment(std::string src_Path)
    {
        seeta::FaceDetection detector("D:/SeetaFaceEngine/include_lib/model/FaceDetection/seeta_fd_frontal_v1.0.bin");
        detector.SetMinFaceSize(40);
        detector.SetScoreThresh(2.f);
        detector.SetImagePyramidScaleFactor(0.8f);
        detector.SetWindowStep(4, 4);
    
        // Initialize face alignment model 
        seeta::FaceAlignment point_detector((MODEL_DIR + "seeta_fa_v1.1.bin").c_str());
    
        //load image
        IplImage *img_grayscale = NULL;
        img_grayscale = cvLoadImage(src_Path.c_str(), 0);
        if (img_grayscale == NULL)
        {
        	return 0;
        }
    
        IplImage *img_color = cvLoadImage(src_Path.c_str(), 1);
        int pts_num = 5;
        int im_width = img_grayscale->width;
        int im_height = img_grayscale->height;
        unsigned char* data = new unsigned char[im_width * im_height];
        unsigned char* data_ptr = data;
        unsigned char* image_data_ptr = (unsigned char*)img_grayscale->imageData;
        int h = 0;
        for (h = 0; h < im_height; h++) 
        {
        	memcpy(data_ptr, image_data_ptr, im_width);
        	data_ptr += im_width;
        	image_data_ptr += img_grayscale->widthStep;
        }
    
    	seeta::ImageData image_data;
    	image_data.data = data;
    	image_data.width = im_width;
    	image_data.height = im_height;
    	image_data.num_channels = 1;
    
    	// Detect faces
    	std::vector<seeta::FaceInfo> faces = detector.Detect(image_data);
    	int32_t face_num = static_cast<int32_t>(faces.size());
    
    	if (face_num == 0)
    	{
    		delete[]data;
    		cvReleaseImage(&img_grayscale);
    		cvReleaseImage(&img_color);
    		return 0;
    	}
    
    	// Detect 5 facial landmarks
    	seeta::FacialLandmark points[5];
    	point_detector.PointDetectLandmarks(image_data, faces[0], points);
    
    	// Visualize the results
    	cvRectangle(img_color, cvPoint(faces[0].bbox.x, faces[0].bbox.y), cvPoint(faces[0].bbox.x + faces[0].bbox.width - 1, faces[0].bbox.y + faces[0].bbox.height - 1), CV_RGB(255, 0, 0));
    	for (int i = 0; i < pts_num; i++)
    	{
    		cvCircle(img_color, cvPoint(points[i].x, points[i].y), 2, CV_RGB(0, 255, 0), CV_FILLED);
    	}
        // 	cvSaveImage("result.jpg", img_color);
    	cvShowImage("dst", img_color);
    	cvWaitKey(0);
    
    	// Release memory
    	cvReleaseImage(&img_color);
    	cvReleaseImage(&img_grayscale);
    	delete[]data;
    }

    关键点检测的结果:

    桃源一向绝风尘柳市南头访隐沦。
    到门不敢题凡鸟,看竹何须问主人。
    城上青山如屋里,东家流水入西邻。
    闭户著书多岁月,种松皆老作龙鳞。

      -- 王维 《春日与裴迪过新昌里访吕逸人不遇》

    上善若水,为而不争。
  • 相关阅读:
    java线程池及创建多少线程合适
    消息队列消息积压了怎么办?
    Redis线程模型
    redis单线程如何支持高并发
    基于redis实现分布式锁
    PHP面试总结
    【转】Redis入门
    面试常考之二叉树
    计算机网络之面试常考
    操作系统之面试常考
  • 原文地址:https://www.cnblogs.com/Bearoom/p/11721774.html
Copyright © 2020-2023  润新知