windows下百度離線人臉識別本地部署與使用(nodejs作客戶端,c++作服務端,socket作通訊)

1.離線人臉識別本地部署css

  詳情請閱讀百度人臉識別官網node

2.nodejs作socket通訊的客戶端c++

  爲何不直接經過調用c++編譯的exe得到人臉識別結果?canvas

  緣由:exe運行時會加載不少模型而消耗不少時間,致使不能實時獲得人臉識別結果;而用socket通訊則只需執行一次加載模型的過程,後面的請求只需直接進行人臉識別檢測而只用100多毫秒獲得結果。api

  1)nodejs將canvas獲得的視頻幀的base64字符串轉換成圖片socket

    

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(同步模式,即獲得人臉識別結果再執行下面的代碼)ui

  

      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服務端spa

  

  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("等待鏈接...\n"); 68 sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen); 69 if (sClient == INVALID_SOCKET) 70 { 71 printf("accept error !"); 72 continue; 73 } 74 printf("接受到一個鏈接:%s \r\n", 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 << "\nis_utf8-" << is_utf8 << "\n" << 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] = '\0'; 108 sendData = arr; 109 } 110 } 111 112 113 } 114 else 115 { 116 //發送數據 117 sendData = "{error:'no data recv'}\n"; 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 }   }
相關文章
相關標籤/搜索