test.cpp 8.18 KB
#include <iostream>
#include <sstream>
#include <fstream>
#include <chrono>
#include <dirent.h>
#include "face_detect.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs/legacy/constants_c.h"
#include "opencv2/imgproc/types_c.h"
#include "time.h"
#include "sys/time.h"
#include "sy_errorinfo.h"
#include "utils.h"
#include "dvpp_process.h"

using namespace std;
using namespace cv;

double msecond() {
    struct timeval tv;
    gettimeofday(&tv, 0);
    return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
}


void getAllNm(std::string pthNm, std::vector<std::string>& fileList)
{
        DIR    *dir;
    struct    dirent    *ptr;
    dir = opendir(pthNm.c_str()); ///open the dir
    int filenum = 0;
    while((ptr = readdir(dir)) != NULL) ///read the list of this dir
    {
        // char* to string
        std::string curNm = ptr->d_name;
        if(curNm != "." && curNm != "..")
        {
                filenum++;
                fileList.push_back(curNm);
                //printf("file %d name: %s\n", filenum, curNm.c_str());
        }
   }
    closedir(dir);
}

void CvBGR2NV21(Mat& bgr, unsigned char* yuv) {
    int stride = (bgr.cols + 15) / 16 * 16;
    int strideH = (bgr.rows + 1) / 2 * 2;
    for (int i = 0; i < bgr.rows; i++) {
        for (int j = 0; j < bgr.cols; j++) {
            int B = bgr.at<cv::Vec3b>(i, j)[0];
            int G = bgr.at<cv::Vec3b>(i, j)[1];
            int R = bgr.at<cv::Vec3b>(i, j)[2];

            int Y = (77 * R + 150 * G + 29 * B) >> 8;
            yuv[i * stride + j] = (Y < 0) ? 0 : ((Y > 255) ? 255 : Y);
            if (i % 2 == 0 && j % 2 == 0) {
                int V = ((-44 * R - 87 * G + 131 * B) >> 8) + 128; ///
                int U = ((131 * R - 110 * G - 21 * B) >> 8) + 128; ///
                yuv[strideH * stride + i / 2 * stride + j] = (V < 0) ? 0 : ((V > 255) ? 255 : V);
                yuv[strideH * stride + i / 2 * stride + j + 1] = (U < 0) ? 0 : ((U > 255) ? 255 : U);
            }
        }
    }
}

int main() {
    cout << fd_get_version() << endl;

    fd_param param;
    param.det_modelNames = "./models/face_detect/face_det_yolov5s_310p.om";
    param.ldmk_modelNames = "./models/face_detect/face_ldmk_310p.om";
    param.pose_modelNames = "./models/face_detect/face_pose_310p.om";
    param.score_modelNames = "./models/face_detect/face_score_310p.om";
    param.fuzzy_modelNames = "./models/face_detect/face_fuzzy_310p.om";
    param.occlusion_modelNames = "./models/face_detect/face_occlusion_310p.om";
    param.thresld = 0.2;
    param.devId = 0;
    param.auth_license = "sy_tongtu_aiplatform_sdk_2023";
    param.facial_fea_point_config = SY_CONFIG_OPEN;		//是否启动关键点检测
    param.pose_config = SY_CONFIG_OPEN;					//是否启动姿态角
	param.quality_config = SY_CONFIG_OPEN;				//是否启动质量检测
	param.score_config = SY_CONFIG_OPEN;				//是否启动人脸置信度  //SY_CONFIG_OPEN  SY_CONFIG_CLOSE
	param.max_result_count = 100;

    void* handle = nullptr;
    cout << "init start " << endl;
    ACL_CALL(aclInit(nullptr), ACL_SUCCESS, SY_FAILED);
    ACL_CALL(aclrtSetDevice(param.devId), ACL_SUCCESS, SY_FAILED);
    aclrtContext ctx;
    ACL_CALL(aclrtCreateContext(&ctx, param.devId), ACL_SUCCESS, SY_FAILED);
    aclrtStream stream = nullptr;
	ACL_CALL(aclrtCreateStream(&stream), ACL_SUCCESS, SY_FAILED);
	DvppProcess* dvpp = new DvppProcess();
	dvpp->InitResource(stream);
    int ret = fd_init(&handle, param);

    if (ret == 0) {
        cout << "init success " << endl;
        const char*  img_file_path="imgs/";

        ifstream infile("list.txt");
        string file;
        while (infile >> file) {
            string filename = "imgs/" + file;
            cout << "img path: " << filename << endl;
            const int batchsize = 1;
            Mat cvImg = imread(filename.c_str());
            sy_img imgs[batchsize];
          
            /*
            ImageData src[batchsize], dvpp_data[batchsize];
            for (int b = 0; b < batchsize; b++) {
                Utils::ReadImageFile(src[b], filename); //将二进制图像读入内存,并读取宽高信息
                ACL_CALL(dvpp->CvtJpegToYuv420sp(dvpp_data[b], src[b]), SY_SUCCESS, SY_FAILED); //解码
                imgs[b].w_ = dvpp_data[b].width;
                imgs[b].h_ = dvpp_data[b].height;
                imgs[b].data_ = dvpp_data[b].data.get();
                cout << dvpp_data[b].size << endl;
            }*/

            uint32_t alignWidth = (cvImg.cols + 15) / 16 * 16;
            uint32_t alignHeight = (cvImg.rows + 1) / 2 * 2;
            uint32_t size = alignWidth * alignHeight * 1.5;
            cout << "opencv:"<<cvImg.cols << " " <<cvImg.rows<< " " <<alignWidth<<" "<<alignHeight <<" "<< size << " " << endl;
            std::shared_ptr<uint8_t> data = shared_ptr<uint8_t>((new uint8_t[size]), 
                [](uint8_t* p) {delete [] p;});
            CvBGR2NV21(cvImg, data.get());
         
            for (int i = 0; i < batchsize; i++) {
                imgs[i].w_ = cvImg.cols;
                imgs[i].h_ = cvImg.rows;
                imgs[i].data_ = data.get();
            }
        
            fd_result results[batchsize];
            for (int fd_i = 0; fd_i < batchsize; fd_i++) {
                results[fd_i].info = new fd_info[50];		//内存由外部申请
            }
            double t1, t2;
            t1 = msecond();
            int ret = fd_detect_batch(handle, imgs, SY_FORMAT_BGR888, batchsize, results);
            t2 = msecond();
            printf("debug mean process time: %.2f\n", (t2 - t1)/batchsize);
            if (SY_SUCCESS != ret) {
                printf("vpr detection process failed!");
                return SY_FAILED;
            }

            // draw results
            for(int b = 0; b < batchsize; b ++){
                printf("debug det num:%d\n",results[b].count);
                for (int j = 0; j < results[b].count; j++) {
                    printf("fd_detect_batch %d - %d %d %d %d %d\n", b, j, results[b].info[j].face_position.left_, results[b].info[j].face_position.top_, results[b].info[j].face_position.width_, results[b].info[j].face_position.height_);
					rectangle(cvImg, Rect(results[b].info[j].face_position.left_, results[b].info[j].face_position.top_, results[b].info[j].face_position.width_, results[b].info[j].face_position.height_), Scalar(0, 0, 255), 3);
                    for (int f = 0; f < 25; f++) {
						cv::circle(cvImg, cv::Point(results[b].info[j].facial_fea_point[f].x_, results[b].info[j].facial_fea_point[f].y_), 1, Scalar(0, 0, 255), 1);
					}

                    cout << "detect_score:" << results[b].info[j].face_pos_score << endl;
                    printf("angle: pitch: %.2f, roll: %.2f, yaw: %.2f, score = %.2f \n", results[b].info[j].pitch, results[b].info[j].roll, results[b].info[j].yaw, results[b].info[j].score);
                    printf("occlusion: %d clarity: %d brightness: %d\n", results[b].info[j].occlusion, results[b].info[j].clarity, results[b].info[j].brightness/*, results[b].info[j].hat, results[b].info[j].glass*/);
                    printf("-----  ldmk = (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", results[b].info[j].facial_fea_point[0].x_, results[b].info[j].facial_fea_point[0].y_, results[b].info[j].facial_fea_point[1].x_, results[b].info[j].facial_fea_point[1].y_, results[b].info[j].facial_fea_point[2].x_, results[b].info[j].facial_fea_point[2].y_, results[b].info[j].facial_fea_point[3].x_, results[b].info[j].facial_fea_point[3].y_);
                    printf("-----  ldmk eye center = (%d,%d) ldmk lip up center = (%d,%d)\n", results[b].info[j].facial_fea_point[6].x_, results[b].info[j].facial_fea_point[6].y_, results[b].info[j].facial_fea_point[8].x_, results[b].info[j].facial_fea_point[8].y_);

                }
            }
            string jpgSaveName = "result/" + file;
            cv::imwrite(jpgSaveName, cvImg);

            for (int fd_i = 0; fd_i < batchsize; fd_i++) {
                delete[] results[fd_i].info;
                results[fd_i].info = NULL;
            }

        }
    }

    dvpp->DestroyResource();
    fd_release(&handle);
    aclFinalize();

    return 0;
}