当前位置:   article > 正文

开放API和SDK的离线人脸识别机研发完成_离线人脸身份识别sdk

离线人脸身份识别sdk

开放API接口协议和SDK二次开放的人脸识别摄像头

摄像头在中国是非常成熟的产品,整个行业趋于垄断和封闭的状态,要找到一款能方便整合到自己系统的摄像头是非常不容易的事情.

OPCOL是一款AI智能的开放API接口和SDK二次开发的人脸识别摄像头。可以非常轻松的接入的已有的业务系统中。

它有如下特点:

  • 开放API+SDK,API为全HTTP restful风格的极容易集成的接口方式,SDK方式为C/C++插件so动态库扩展方式
  • 完全离线模式,不依赖任何第三方云服务器,数据不会传输到任何第三方服务器,让用户隐私得到保障
  • 设备支持2万张人脸库,人脸识别毫秒级响应,深度学习算法实现人脸检测、跟踪、去重、质量检测。
  • 采用SONY CMOS图像传感器
  • 最大画面尺寸 1080P(1920*1080),最大支持2路视频流和1路JPG图像抓拍通道

不支持判断是否活体检测

API详细说明链接

https://gitee.com/imlsq/pubdoc/blob/master/opcolv300.md

实物图

 

API介绍

设备提供如下3种途径集成到第三应用

  • HTTP协议接口.
  • TCP/ip长连接协议对接
  • SDK用户自定义研发SO插件集成

TTP方式提供基本的,最简单的对接方式

 

HTTP请求认证


通过http访问设备的请求需要加上签名安全认证码,以确定合法来源.url格式如下

 

http://${ip}:${port}/xxx?sign=${xxx}&token=请求令牌,创建一个随机UUID
*类型说明
ipstring设备IP地址(参考内网搜索设备获取ip)
signstring签名串,token+key组合md5算法之后16进制字符串(32位)
key请参考下面如何签名KEY的说明
tokenstring请求令牌,客户端每次请求创建一个新的uuid,token不能重复使用

 

签名KEY


用户名和密码登录验证之后会返回md5签名key。

 

/api/login

method:post
Content-Type: application/json

Request body:

 

{"username":"admin","password":"xxxx"}
*类型说明
usernamestring用户名固定admin
passwordstring密码

这个url请求无需签名,主机验证用户名和密码之后会返回签名md5 key,后续url请求用这个md5 key进行签名访问

返回结构

 

  1. {
  2. "code": 20000,
  3. "data": {
  4. "accessKey": "xxxxx"
  5. }
  6. }
*类型说明
codestring20000,设备有处理请求
accessKeystring签名KEY,后续请求用这个md5 key签名访问
可以把这个key缓存在应用端,设备重置操作KEY会变化

 

修改密码


 

/api/set_password?old_password=x&new_password=x

method:get

请求参数:

*类型说明
old_passwordstring密码
new_passwordstring新密码

 

设置WIFI


 

/api/set_wifi

method:post
Content-Type: application/json

Request body:

 

{"ssid":"x","password":"x"}
*类型说明
ssidstringwifi ssid
passwordstringwifi password

Response body:

 

  1. {
  2. "code": 20000,
  3. "bizCode": 200
  4. }

 

设备上报接口设置


当设备端有移动侦测或识别到人脸时会通过此接口设置的URL上报。

 

/api/set_3rd_url?url=http://your_url&key=xxx

method:get

*类型说明
urlstring设备数据通过http的 POST提交到此URL,数据格式参考 "人脸识别数据结构说明"
keystring预留

人脸识别数据结构说明

 

  1. {
  2. "event_type": 4,
  3. "time": "1603934998092",
  4. "mac": "76:be:d8:75:29:f0",
  5. "sign": "x",
  6. "track_id": "6",
  7. "score": 86.57,
  8. "person_id": "10010001",
  9. "person_name": "Mr.luo",
  10. "face_base64": "xxxxx",
  11. "origin_base64": "xxxx",
  12. "blur":0.1,
  13. "goodness":0.9
  14. }
*类型说明
event_typeint4 人脸识别事件
timestring事件发生时间
macstring设备mac地址
signstring签名串,用于验证是否合法请求源,md5(time+key+mac) 32位16进制字符串
track_idstring人脸跟踪ID
scorestring相似度,分值越高,相似度越高,满分100,通常大于70分判断为相同的人
person_idstring搜索到的相似度最高的人脸库的人脸ID
person_namestring搜索到的相似度最高的人脸库的人名字
face_base64string抓拍的人脸图像数据(base64编码)
origin_base64string抓拍的整个图像数据(base64编码)
blurfloat人脸模糊程度属性(0〜1,0代表最清晰,1代表最模糊)
goodnessfloat人脸品质,根据pose/blur,得到的人脸分数(0〜1,1是最高分,表示人脸好

 

人脸上传


 

/api/face_upload

method:post

Request body:

 

  1. 人脸照片的base64编码16进制字符串
  2. /9j/4AAQSkZJRgABAQ....

整个请求Body全部为照片的base64编码字符串,不能有其他数据

Response body:

 

  1. {
  2. "code": 20000,
  3. "bizCode": 200,
  4. "data": {
  5. "id": 896
  6. }
  7. }
*类型说明
codeint20000为上传成功
idint人脸保存的唯一ID

 

人脸库查询


 

/api/face_list?page=1&limit=16

method:get

Request body:

*类型说明
pageint分页查询
limitint每页记录数量

Response body:

 

  1. {
  2. "code": 20000,
  3. "data": {
  4. "total": 2,
  5. "list": [{
  6. "id": 896,
  7. "file": "/face/896.jpg",
  8. "state": "1"
  9. }, {
  10. "id": 801,
  11. "file": "/face/801.jpg",
  12. "state": "2",
  13. "biz_id": "10010001",
  14. "name": "Mr.luo"
  15. }]
  16. }
  17. }
*类型说明
idint人脸保存的唯一ID
filestring人脸图片路径
stateint状态:1未入库,2已入库
biz_idstring身份ID这个字段值会作为上报接口中对应的person_id字段值
namestring名字这个字段值会作为上报接口中对应的person_name字段值

 

设置人脸身份ID


根据人脸保存的唯一ID设置照片身份ID和名字

 

/api/face_edit

method:post
Content-Type: application/json

Request body:

 

{"id":801,"biz_id":"xx","name":"xxx"}
*类型说明
biz_idstring身份ID这个字段值会作为上报接口中对应的person_id字段值
namestring名字这个字段值会作为上报接口中对应的person_name字段值

 

人脸识别记录查询


分页查询人脸识别历史记录

 

/api/recognition_list?page=1&limit=16

method:get

*类型说明
pageint页码
limitint每页记录数

response body

 

  1. {
  2. "code": 20000,
  3. "data": {
  4. "total": 9,
  5. "list": [
  6. {
  7. "id": 10,
  8. "face": "./track_out/10.jpg",
  9. "time": "1606189079985",
  10. "person_id": "",
  11. "person_face": "",
  12. "name": "",
  13. "origin_file": "./track_out/origin_10.jpg",
  14. "video_file": "",
  15. "blur": "0.1",
  16. "goodness": "1",
  17. "score": "0"
  18. },
  19. {
  20. "id": 9,
  21. "face": "./track_out/9.jpg",
  22. "time": "1606188705928",
  23. "person_id": "",
  24. "person_face": "",
  25. "name": "",
  26. "blur": "0.1",
  27. "goodness": "0.9",
  28. "score": "0"
  29. }
  30. ]
  31. }
  32. }
*类型说明
idintid
facestring抓拍的人脸保存路径
timestring识别时间(毫秒)
person_idstring识别到的人脸编号
person_facestring识别到的人脸路径
namestring识别到的人名字
origin_filestring抓拍的整画面图
video_filestring抓拍的视频文件
blurfloat人脸模糊程度属性(0〜1,0代表最清晰,1代表最模糊)
goodnessfloat人脸品质,根据pose/blur,得到的人脸分数(0〜1,1是最高分,表示人脸好
scorestring相似度

 

人脸入库


只有进行了入库操作的人脸才会参与识别

 

/api/face_extract_feature?id=x

method:get

*类型说明
idint人脸保存的唯一ID

response body

 

  1. {
  2. "code": 20000,
  3. "bizCode": 200
  4. }
*类型说明
bizCodeint200为成功

 

内网搜索设备


通过udp协议给5634端口广播“hi”,同一局域网内的设备会回复自身主机信息。
JAVA搜索例子

 

  1. DatagramSocket dgSocket = new DatagramSocket();
  2. dgSocket.setSoTimeout(1000);
  3. byte b[] = "hi\n".getBytes();
  4. DatagramPacket dgPacket = new DatagramPacket(b, b.length, InetAddress.getByName("255.255.255.255"), 5634);
  5. dgSocket.send(dgPacket);
  6. byte[] receiveBuf = new byte[256];
  7. DatagramPacket dp = new DatagramPacket(receiveBuf, 0, receiveBuf.length);//定义一个接收的包
  8. try {
  9. while (true) {
  10. dgSocket.receive(dp);
  11. if (dp.getLength() > 0) {
  12. String rs = new String(dp.getData(), 0, dp.getLength());
  13. //id:xxxxxx,v:xxxx,m:xxxxx
  14. String rs_slipt[] = rs.split(",");
  15. if ((cMap.get(rs) == null) && (rs_slipt.length > 1)) {
  16. String id = rs_slipt[0].replaceAll("id:", "");
  17. System.out.println("id:"+id);
  18. System.out.println("ip:"+dp.getAddress().getHostAddress());
  19. }
  20. }
  21. }

iOS/C

 

  1. int socketfd;
  2. socklen_t addr_len;
  3. char hi[]="Hi";
  4. struct sockaddr_in server_addr;
  5. if((socketfd = socket(PF_INET,SOCK_DGRAM,0)) < 0)
  6. {
  7. perror("socket");
  8. return -1;
  9. }
  10. int i=1;
  11. socklen_t len = sizeof(i);
  12. setsockopt(socketfd,SOL_SOCKET,SO_BROADCAST,&i,len);
  13. struct timeval tv_out;
  14. tv_out.tv_sec = 1;//等待5秒
  15. tv_out.tv_usec = 0;
  16. setsockopt(socketfd,SOL_SOCKET,SO_RCVTIMEO,&tv_out, sizeof(tv_out));
  17. memset(&server_addr,0,sizeof(server_addr));
  18. server_addr.sin_family = AF_INET;
  19. server_addr.sin_addr.s_addr = inet_addr("255.255.255.255");
  20. server_addr.sin_port = htons(atoi("5634"));
  21. addr_len=sizeof(server_addr);
  22. sendto(socketfd,hi,strlen(hi),0,(struct sockaddr*)&server_addr,addr_len);
  23. printf("Broadcast message to port 5634\n");
  24. char buff[256];
  25. memset(&buff, 0, 256);
  26. struct sockaddr_in sddr;
  27. int n;
  28. len = sizeof(sddr);
  29. n = recvfrom(socketfd, buff, 256, 0, (struct sockaddr*)&sddr,&len);
  30. if (n>0){
  31. printf("%s,server ip=%s\n",buff,inet_ntoa(sddr.sin_addr));
  32. }
  33. close(socketfd);

 

视频抓拍数据流


待完善

 

TCP/IP协议对接


支持TCP长连接对接第三方服务器,在TCP通道可以发送指令控制设备
待完善

 

获取实时视频流(H264)


待完善

 

P2P对接协议


待完善

 

RTMP协议对接


待完善

 

SDK二次开发说明


可以二次开发扩展程序(c/c++),FTP上传到设备或NFS挂载调试。
设备应用框架采用linux so动态链接库方式扩展功能

需要具备的知识:
需要熟练掌握C/C++编程
熟悉Linux操作系统基本知识

 

开发第一个Hello程序


安装Linux 32位操作系统

建议虚拟机,Ubuntu18.04版本,如果是64位,需要安装32位扩展.

安装HISI Arm处理器编译器

arm-himix200-linux
下载地址 百度网盘
链接:https://pan.baidu.com/s/1IHAlX3NwITqPzXP55N4BZQ
提取码:ibn1

 

  1. tar -xzvf arm-himix200-linux.tgz
  2. cd arm-himix200-linux
  3. chmod +x ./arm-himix200-linux.install
  4. ./arm-himix200-linux.install

执行下面命令确认编译器是否安装成功

 

arm-himix200-linux-gcc -v

 

  1. Using built-in specs.
  2. COLLECT_GCC=arm-himix200-linux-gcc
  3. COLLECT_LTO_WRAPPER=/opt/hisi-linux/x86-arm/arm-himix200-linux/host_bin/../libexec/gcc/arm-linux-gnueabi/6.3.0/lto-wrapper
  4. Target: arm-linux-gnueabi

编译第一个程序Hello

解压OPCOL SDK之后,看到如下目录结构

 

  1. .OPCOLV300
  2. --3rd
  3. --admin
  4. --doc
  5. --hisi
  6. --plugin
  7. │ │--hello
  8. │ │--|--Makefile
  9. --sdkinclude
  10. --cfg.mak
  11. --Makefile.param

在hello的目录下执行

 

Make

编译成功之后生成了 libhello.so
把libhello.so拷贝到设备上的/app/plugin目录下
用telnet客户端连接到设备
执行启动主程序

 

  1. cd /app
  2. ./run.sh

hello.c程序解析

 

  1. #include "opcol.h" //SDK头文件
  2. #include <stdlib.h>
  3. int OPCOL_plugin_init(OPCOL_PLUGIN_CONTEXT_S *context)
  4. {
  5. //扩展SO,初始化入口
  6. printf("Hi,i am opcol\n");
  7. return 0;
  8. }
  9. int OPCOL_plugin_free()
  10. {
  11. //扩展SO,释放函数
  12. return 0;
  13. }

有2个函数
OPCOL_plugin_init为so的入口函数,主程序主动调用用户二次开发的so
OPCOL_plugin_free 为主程序退出时调用的函数

 

SO里获取视频流


设备里有2路视频流:1路1080P 30帧/s;1路360P 20帧/s

 

  1. #include "opcol.h" //SDK头文件
  2. #include <stdlib.h>
  3. int SNB_event_handle(OPCOL_EVENT_TYPE_E eventType, void *pstData);
  4. int OPCOL_plugin_init(OPCOL_PLUGIN_CONTEXT_S *context)
  5. {
  6. //扩展SO,初始化入口
  7. //注册事件回调函数,当有视频数据时,回调my_event_handle函数
  8. context->eventListener = &my_event_handle;
  9. return 0;
  10. }
  11. int OPCOL_plugin_free()
  12. {
  13. //扩展SO,释放函数
  14. return 0;
  15. }
  16. //视频数据回调函数
  17. int SNB_event_handle(OPCOL_EVENT_TYPE_E eventType, void *pstData)
  18. {
  19. if (eventType != OPCOL_EVENT_VENC_STREAM)
  20. {
  21. return 0;
  22. }
  23. OPCOL_VENC_STREAM_S *param = (OPCOL_VENC_STREAM_S *)pstData;
  24. //视频流数据处理,例如保存到文件,提交到云服务器等
  25. //....do something
  26. if (param->chn == 1)
  27. {
  28. //第1通道视频数据,拷贝到内存
  29. char *cache=(char *)malloc(1024*1024);
  30. int len=0;
  31. for (i = 0; i < param->pstStream->u32PackCount; i++)
  32. {
  33. memcpy(cache + len, pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset, pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset);
  34. len = len + pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset;
  35. }
  36. free(cache);
  37. }
  38. return 0;
  39. }

 

SQLite3数据库

 

  1. #include "opcol.h" //SDK头文件
  2. #include <stdlib.h>
  3. #include "sqlite3.h"
  4. sqlite3 *db_handler;
  5. int SNB_event_handle(OPCOL_EVENT_TYPE_E eventType, void *pstData);
  6. int OPCOL_plugin_init(OPCOL_PLUGIN_CONTEXT_S *context)
  7. {
  8. //扩展SO,初始化入口
  9. db_handler = context->db_handler; //指向数据库指针
  10. //do something about sqlite3 db
  11. //.....
  12. return 0;
  13. }
  14. int OPCOL_plugin_free()
  15. {
  16. //扩展SO,释放函数
  17. return 0;
  18. }

 

SDK函数

 

  1. //设置视频通道的帧率
  2. int OPCOL_set_h264_frame_rate(int chn, int rate);
  3. //设置视频通道的码流
  4. int OPCOL_set_h264_bit_rate(int chn, int rate);
  5. //编码一帧图像RAW(yuv420)数据到JPG
  6. int OPCOL_encode_jpeg(VIDEO_FRAME_INFO_S *frame, unsigned char *out_buffer, int *out_len);
  7. //在视频画面画框
  8. int OPCOL_draw_rect(int x, int y, int w, int h);
  9. //清除视频画面画框
  10. int OPCOL_clear_rect();
  11. //侦听系统事件
  12. void OPCOL_plugin_dispath_event(OPCOL_EVENT_TYPE_E eType, void *data);
  13. //设置系统密码
  14. int OPCOL_set_password(const char *old_password, const char *new_password);
  15. //获取签名KEY
  16. OPCOL_ACCESS_INFO *OPCOL_get_access_info();
  17. //设置音视频参数,如视频镜像翻转,快门曝光时间
  18. int OPCOL_set_video_audio_attr(OPCOL_VIDEO_AUDIO_ATTR *video_audio_attr);
  19. //获取音视频参数
  20. OPCOL_VIDEO_AUDIO_ATTR *OPCOL_get_video_audio_attr();
  21. //获取网络配置参数,如WIFI,IP地址,mac等
  22. OPCOL_NET_INFO *OPCOL_get_net_info();
  23. //设置网络参数,如WFI,ip
  24. int OPCOL_set_net_info(OPCOL_NET_INFO *net_info);

系统事件,系统事件发生时,会广播每个so插件,每个插件在入口函数里注册事件侦听函数
如下注册my_event_handle为事件处理函数,具体看SO里获取视频流例子代码

context->eventListener = &my_event_handle;

 

  1. typedef enum _opcolEVENT_TYPE_E
  2. {
  3. OPCOL_EVENT_VENC_STREAM = 0, //有新的视频流帧数据
  4. OPCOL_EVENT_YUV_FRAME, //新的yuv420 raw数据帧
  5. OPCOL_EVENT_HTTP_REQ, //当收到HTTP请求事件
  6. OPCOL_EVENT_DISK_SPACE_COUNTED, //磁盘统计信息事件
  7. OPCOL_EVENT_FACE_RECOGNITION, //侦测到人脸时事件
  8. } OPCOL_EVENT_TYPE_E;
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/709693
推荐阅读
相关标签
  

闽ICP备14008679号