憨豆爱上笨笨 发表于 2018-8-15 10:03:28

基于人脸识别SDK实现usb摄像头实时人脸比对

1、在原有的SDK中FaceDetectVideo文件中.cpp文本中更改成以下程序
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

#ifdef _MS_VER
#ifdef _DEBUG
#pragma comment(lib, "opencv_core2413d.lib")
#pragma comment(lib, "opencv_highgui2413d.lib")
#pragma comment(lib, "opencv_imgproc2413d.lib")
#else
#pragma comment(lib, "opencv_core2413.lib")
#pragma comment(lib, "opencv_highgui2413.lib")
#pragma comment(lib, "opencv_imgproc2413.lib")
#endif
#endif

using namespace std;
using namespace cv;

#include "firefly_faceverify.h"

int CheckImageType(const unsigned char *image_data,
        const rr_image_type image_type,
        const int image_width,
        const int image_height)
{
        int cv_type = (int)rr_image_type::RR_IMAGE_MAX;

        switch (image_type)
        {
                case rr_image_type::RR_IMAGE_BGR8UC3:
                {
                        cv_type = CV_8UC3;
                }
                break;

                case rr_image_type::RR_IMAGE_BGRA8UC4:
                {
                        cv_type = CV_8UC4;
                }
                break;

                case rr_image_type::RR_IMAGE_GRAY8UC1:
                {
                        cv_type = CV_8UC1;
                }
                break;

                default:
                        return RR_E_ILLEGAL_ARGUMENT;
        }

        //
        cv::Mat img;
        try
        {
                img = cv::Mat(cv::Size(image_width, image_height), cv_type, (void*)image_data).clone();
        }
        catch (cv::Exception& e)
        {
                if (e.code == CV_StsNoMem)
                {
                        return RR_E_NO_MEMORY;
                }

                return RR_E_FAIL;
        }
        if (img.empty() == true)
        {
                return RR_E_FAIL;
        }

        cv::namedWindow("CheckImageType");
        cv::imshow("CheckImageType", img);
        cv::waitKey(0);

        return RR_OK;
}

int FaceVerify(const rr_handle_t hDetector, const rr_handle_t hVerifier, char img_file[], char filename[], float* p_score)//第一步,尝试更改变量类型
{
        int ret = 0;

      #define FEATURE_LEN 256
        float feature1 = { 0 };
        float feature2 = { 0 };
        int feature_len = FEATURE_LEN;

        ///
        cv::Mat img;
        rr_face_t* faces_array = NULL;
        int faces_count = 0;

        /// feature1
        img = cv::imread(img_file);

        ret = firefly_fd_detect_image(hDetector, img.data, RR_IMAGE_BGR8UC3, img.cols, img.rows, &faces_array, &faces_count);
        if (ret != RR_OK)
        {
                printf("firefly_fd_detect_image() failed: %d\n", ret);
                return -1;
        }

        if (faces_count == 0)
                return -1;

        ret = firefly_fv_extract_feature(hVerifier, img.data, RR_IMAGE_BGR8UC3, img.cols, img.rows, faces_array.landmarks, 5, feature1, FEATURE_LEN);
        if (ret != RR_OK)
        {
                printf("firefly_fv_extract_feature() failed: %d\n", ret);
                return -1;
        }

        firefly_fd_free_detect_result(faces_array);
      /// feature2
      img = cv::imread(filename);
        ret = firefly_fd_detect_image(hDetector, img.data, RR_IMAGE_BGR8UC3, img.cols, img.rows, &faces_array, &faces_count);
        if (ret != RR_OK)
        {
                printf("firefly_fd_detect_image() failed: %d\n", ret);
                return -1;
        }

        if (faces_count == 0)
                return -1;

        ret = firefly_fv_extract_feature(hVerifier, img.data, RR_IMAGE_BGR8UC3, img.cols, img.rows, faces_array.landmarks, 5, feature2, FEATURE_LEN);
        if (ret != RR_OK)
        {
                printf("firefly_fv_extract_feature() failed: %d\n", ret);
                return -1;
        }

        firefly_fd_free_detect_result(faces_array);

        ///
        float score = firefly_fv_compare_feature(feature1, feature2, feature_len);
        *p_score = score;

        return 0;
}

int faceverify()
{

    char img_file;
    sprintf(img_file, "test/test%d.jpg", 1);//保存命名图片:测试中可进行自己保存
   // string img_file = "/home/sljt/data/openface/openface_sdk/samples/FaceDetectVideo/test/test1.jpg";
      char filename;
       float fScore = 0.0;
       cv::Mat img;
       int ret = 0;

        string detect_model;
        detect_model = "../../models";

        string verify_model;
        verify_model = "../../models";

        ///
        rr_handle_t hDetector = NULL;
        hDetector = firefly_fd_init_detector(detect_model.c_str(), RR_FD_VERSION);
        if (hDetector == NULL)
        {
                printf("firefly_fd_init_detector() failed\n");
                return -1;
        }

        rr_handle_t hVerifier = firefly_fv_init_verifier(verify_model.c_str());
        if (hVerifier == NULL)
        {
                printf("firefly_fv_init_verifier() failed!\n");
                return -1;
        }
//测试图像,进行人脸对比   
for(int i=0;i<4;i++)
{
   sprintf(filename, "test-images/test%d.jpg", i);//保存命名图片:测试中可进行自己保存
      
    ret = FaceVerify(hDetector, hVerifier, img_file, filename, &fScore);
      if (ret == 0)
               {
                printf("verify: %s vs %s\n", img_file, filename);
                     if(fScore >= 0.85)
                     {
                     printf("score: %f\n", fScore);
                     printf("test%d\n",i);
                     img = cv::imread(filename);
                     
                     break;
                     }
                     printf("loading...\n\n");

               }
   }
         cv::namedWindow("test");
         cv::imshow("test", img);
         cv::waitKey(0);
   
        firefly_fd_deinit_detector(hDetector);
        firefly_fv_deinit_verifier(hVerifier);

        printf("press ENTER to exit");
        getchar();

        return 0;            

}

int copy_capture(cv::Mat frame,float x,float y,float w, float h)
{
                   if(!frame.data){printf("读取srcImage错误\n"); return false;}
                  printf(".........%d\n",*frame.data);
                  cv::Mat m_roi = frame(cv::Rect(x-10,y-10,w+30,h+30));
                   if(!m_roi.data){printf("读取srcImage错误\n"); return false;}
                  printf(".........%d\n",*m_roi.data);
                  cv::Mat img3 = m_roi.clone();
                  cv:: Mat G;

                  img3.copyTo(G);

                   if(!G.data){printf("读取logoImage错误\n"); return false;}
                  printf(".........%d\n",*G.data);
            
                     imwrite("/home/sljt/data/openface/openface_sdk/samples/FaceDetectVideo/test/test2.jpg",frame);
                     imwrite("/home/sljt/data/openface/openface_sdk/samples/FaceDetectVideo/test/test1.jpg",G);
            
}

int main()
{
      int flag = 1;
        string model_dir; // &Auml;&pound;&ETH;&Iacute;&Icirc;&Auml;&frac14;&thorn;&frac14;&ETH;
        model_dir = "../../models";
      int iFrame=0;
        int ret = 0;
      cv::VideoCapture capture;

        rr_handle_t hDetector = NULL;
        hDetector = firefly_fd_init_detector(model_dir.c_str(), RR_FD_VERSION);
        if (hDetector == NULL)
        {
                printf("firefly_fd_init_detector() failed\n");
                return -1;
        }

      capture.open(1);

   while(flag)
       {
         
             cv::Mat frame;
             ret = capture.read(frame);
             iFrame++;
            
                rr_face_t* faces_array = NULL;
                int faces_count = 0;

                // you could test image_data, image_type and show image, when you met image_type problem.
                //if (CheckImageType(img.data, rr_image_type::RR_IMAGE_BGR8UC3, img.cols, img.rows) != RR_OK) printf("img data or type ERROR!\n");
                ret = firefly_fd_detect_image(hDetector, frame.data, rr_image_type::RR_IMAGE_BGR8UC3, frame.cols, frame.rows, &faces_array, &faces_count);
                if (ret != RR_OK)
                {
                        printf("firefly_fd_detect_image() failed: %d\n", ret);
                        printf("press ENTER to continue");
                        getchar();
                        continue;
                }

                ///
                // frame #
                string info = "# " + to_string(iFrame);
                cv::Point ptText(100, 30);
               
                putText(frame, info.c_str(), ptText, CV_FONT_HERSHEY_PLAIN, 1.2, cv::Scalar(0, 0, 255), 1);

                // draw faces rect and id
                for (int i = 0; i<faces_count; i++)
                {
                        float x = faces_array.rect.left;
                        float y = faces_array.rect.top;
                        float h = faces_array.rect.bottom - faces_array.rect.top + 1;
                        float w = faces_array.rect.right - faces_array.rect.left + 1;
                       
                        cv::Point pt(faces_array.rect.left, faces_array.rect.top);
                        std::string strText = to_string(faces_array.id) + " " + to_string(faces_array.confidence);

                        printf("long double number:%f\n",faces_array.confidence);
                     float number=0.9999;
               if(faces_array.confidence >= number && (*frame.data >= 200) )
                  {
                     copy_capture(frame,x,y,w,h);
                  
                     flag = 0;
                     break;

                   }
                        putText(frame, strText.c_str(), pt, CV_FONT_HERSHEY_PLAIN, 1.2, cv::Scalar(0, 0, 255), 1);
                        cv::rectangle(frame, cv::Rect(x, y, w, h), cv::Scalar(255, 0, 0), 2);

               }
               

               firefly_fd_free_detect_result(faces_array);
                cv::namedWindow("video");
                cv::imshow("video", frame);
                cv::waitKey(1);
          if(!cvGetWindowHandle("video"))
               {
                break;
                }
    }
      faceverify();//人脸比对
      capture.release();
        firefly_fd_deinit_detector(hDetector);

        return 0;
}
问题:占用CPU过大,可采用线程和数据结构解决

xupeili2006 发表于 2019-1-16 21:54:36

楼主,CPU占用率大概多少呢

憨豆爱上笨笨 发表于 2019-3-4 14:43:48

xupeili2006 发表于 2019-1-16 21:54
楼主,CPU占用率大概多少呢

99%
页: [1]
查看完整版本: 基于人脸识别SDK实现usb摄像头实时人脸比对