zoukankan      html  css  js  c++  java
  • windows下百度离线人脸识别本地部署与使用(nodejs做客户端,c++做服务端,socket做通信)

    1.离线人脸识别本地部署

      详情请阅读百度人脸识别官网

    2.nodejs做socket通信的客户端

      为什么不直接通过调用c++编译的exe获得人脸识别结果?

      原因:exe运行时会加载很多模型而消耗很多时间,导致不能实时得到人脸识别结果;而用socket通信则只需执行一次加载模型的过程,后面的请求只需直接进行人脸识别检测而只用100多毫秒得到结果。

      1)nodejs将canvas得到的视频帧的base64字符串转换成图片

        

    var image = query.image;
    var base64Data = image.replace(/^data:image/w+;base64,/, "");
    var dataBuffer = new Buffer(base64Data, 'base64');
    fs.writeFile("image.png", dataBuffer, function(err) {
        if(err){
    	console.log("保存成功!");
        }else{
    	console.log("保存成功!");
        }
    });
    		    
    

      2)创建socket(同步模式,即得到人脸识别结果再执行下面的代码)

      

          var result = '';
    
             var net = require('net');
             var port = 8588;
             var host = '127.0.0.1';
          //等待检测结果出来
             result = await new Promise(
                function (resolve, reject) {
              //创建socket客户端 var client= new net.Socket(); client.setEncoding('binary'); //连接到服务端 client.connect(port,host,function(){
                 //向服务端发送数据 client.write('D
    :\wamp\wamp64\www\eggs\image.png');  }); client.on('data',function(data){ console.log('from server:'+ data);  console.log(data); result = data; //得到服务端返回来的数据 resolve({"cod"e: 1, "data": result, "msg": 'success' }) }); client.on('error',function(error){ //错误出现之后关闭连接  console.log('error:'+error); reject({"code": 0, "data": "", "msg": error }); // client.destory(); }); client.on('close',function(){ //正常关闭连接 resolve({"code": 1, "data": "", "msg": 'socket closed' }); console.log('Connection closed'); }); } )

        return result; //result = {"code":1 , "data":xxx, "msg": xxx};

    3.c++ 做socket服务端

      

      1   int main(){  
         //std::cout << "in main" << std::endl; 2 //api实例指针 3 BaiduFaceApi *api = new BaiduFaceApi(); 4 //初始化sdk 5 // 若采用证件照模式,请把id_card设为true,否则为false,证件照模式和非证件照模式提取的人脸特征值不同, 6 // 不能混用 7 bool id_card = false; 8 bool is_authed = true; 9 int suc = api->sdk_init(id_card); 10 if (suc != 0) 11 { 12 std::cout << " err{authed is failed} "<< std::endl; 13 getchar(); 14 is_authed = false; 15 //return 0; 16 } 17 18 std::time_t time_begin = get_timestamp(); 19 /*std::cout << "start tracking" << std::endl; 20 for (int i = 0; i < argc; i++) 21 { 22 std::cout << "argv is" << i << argv[i] << "end print " << std::endl; 23 }*/ 24 25 WSACleanup(); 26 27 //初始化WSA 28 WORD sockVersion = MAKEWORD(2, 2); 29 WSADATA wsaData; 30 if (WSAStartup(sockVersion, &wsaData) != 0) 31 { 32 return 0; 33 } 34 35 //创建套接字 36 SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 37 if (slisten == INVALID_SOCKET) 38 { 39 printf("socket error !"); 40 return 0; 41 } 42 43 //绑定IP和端口 44 sockaddr_in sin; 45 sin.sin_family = AF_INET; 46 sin.sin_port = htons(8588); 47 sin.sin_addr.S_un.S_addr = INADDR_ANY; 48 if (::bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) 49 { 50 printf("bind error !"); 51 } 52 53 //开始监听 54 if (listen(slisten, 5) == SOCKET_ERROR) 55 { 56 printf("listen error !"); 57 return 0; 58 } 59 60 //循环接收数据 61 SOCKET sClient; 62 sockaddr_in remoteAddr; 63 int nAddrlen = sizeof(remoteAddr); 64 char revData[2550* 40];
         //不断监听接口获取客户端参数
    65 while (true) 66 { 67 printf("等待连接... "); 68 sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen); 69 if (sClient == INVALID_SOCKET) 70 { 71 printf("accept error !"); 72 continue; 73 } 74 printf("接受到一个连接:%s ", inet_ntoa(remoteAddr.sin_addr)); 75 76 //接收数据 77 long long int ret = recv(sClient, revData, 2550*40, 0); 78 const char * sendData = ""; 79 //如果没接收到数据 80 if (ret > 0) 81 { 82 //如果百度人脸识别验证证书不通过 83 if (!is_authed) 84 { 85 sendData = "error:authed is failed"; 86 } 87 else 88 { 89 revData[ret] = 0x00; 90 printf(revData);
                //检测图片
    91 string res = test_face_attr(api, revData); 92 if (res == "") 93 { 94 sendData = "error:no people"; 95 } 96 else 97 { 98 bool is_utf8 = is_str_utf8(res.c_str()); 99 std::cout << " is_utf8-" << is_utf8 << " " << std::endl; 100 std::cout << res << endl; 101 102 printf(res.c_str()); 103 //发送数据 104 char arr[100]; 105 106 int len = res.copy(arr, 100); 107 arr[len] = ''; 108 sendData = arr; 109 } 110 } 111 112 113 } 114 else 115 { 116 //发送数据 117 sendData = "{error:'no data recv'} "; 118 } 119 120 121 send(sClient, sendData, strlen(sendData), 0); 122 std::time_t time_end = get_timestamp(); 123 //std::cout << "tracking_result is:" << res << std::endl; 124 std::cout << "time cost is :" << time_end - time_begin << "ms" << std::endl; 125 closesocket(sClient); 126 }
       }

        

  • 相关阅读:
    LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP
    洛谷 P1969 积木大赛 —— 水题
    洛谷 P1965 转圈游戏 —— 快速幂
    洛谷 P1970 花匠 —— DP
    洛谷 P1966 火柴排队 —— 思路
    51Nod 1450 闯关游戏 —— 期望DP
    洛谷 P2312 & bzoj 3751 解方程 —— 取模
    洛谷 P1351 联合权值 —— 树形DP
    NOIP2007 树网的核
    平面最近点对(加强版)
  • 原文地址:https://www.cnblogs.com/indifferent/p/11880706.html
Copyright © 2011-2022 走看看