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 }
   }

    

原文地址:https://www.cnblogs.com/indifferent/p/11880706.html