天天看点

对接商汤摄像头详细步骤准备工作

对接商汤摄像头详细步骤

    • 已实现接口
  • 准备工作
    • STNetSDK(商汤摄像头dll文件函数)

题外话:博主写这篇文章的背景也很简单, 公司需要对接商汤的DVR摄像头,捕捉其人脸识别的数据。坑爹的是商汤没有出Java的Demo, 对方负责对接的人员又不懂技术,只能自己硬啃. 写这篇博客的目的很简单,就是为各位有需要对接商汤摄像头的道友提供一些小小的帮助.

已实现接口

  1. 设备初始化接口);
  2. 获取版本接口;
  3. 设置断线重连回调接口;
  4. 设置连接设备超时时间和尝试次数;
  5. 登陆接口功能
  6. 断网重连功能
  7. 对接人脸识别功能

准备工作

  1. 将xxx.dll文件放入项目根路径;
  2. 将jna.jar包引入项目中,若是maven项目可以引入jna的仓库;
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>4.1.0</version>
        </dependency>
           

STNetSDK(商汤摄像头dll文件函数)

public class STNetSDK {
    private static final Logger log = Logger.getLogger("STNetSDK");
    private static DvrService dvrService = SpringContextHolder.getBean(DvrService.class);

    public static final int ST_MAX_POLYGON_NUM = 16;// 多边形最大顶点个数
    public static final int ST_MAX_CANDIDATE_NUM = 50;// 多边形最大顶点个数
    public static final int MAX_PATH = 260;// 多边形最大顶点个数
    public static final int ST_MAX_PERSON_NAME_LEN = 64;// 人员名字最大长度
    public static final int ST_MAX_PERSON_ID_LEN = 32;// 人员id最大长度
    public static final int ST_MAX_PERSON_IMAGE_NUM = 48;// 每个人员对应的最大人脸图片数
    public static final int ST_MAX_PROVINCE_NAME_LEN = 64;// 省份名称最大长度
    public static final int ST_MAX_CITY_NAME_LEN = 64;// 城市名称最大长度
    public static final int NET_COUNTRY_LENGTH = 3;// 国家缩写长度
    public static final int ST_COMMON_STRING_16 = 16;// // 通用字符串长度16
    public static final int NET_COMMENT_LENGTH = 100;// 备注信息长度
    public static final int NET_GROUPID_LENGTH = 64;// group id 信息长度
    public static final int NET_GROUPNAME_LENGTH = 128;// group name 信息长度
    public static final int ST_COMMON_STRING_128 = 128;// 通用字符串长度128
    public static final int ST_MAX_NAME_LEN = 16;// 通用名字字符串长度
    public static final int ST_SERIALNO_LEN = 48;              // 设备序列号字符长度

    public static class NET_DEVICEINFO_Ex extends Structure {
        public byte[] sSerialNumber = new byte[ST_SERIALNO_LEN];// 序列号
        public int nAlarmInPortNum;// DVR报警输入个数
        public int nAlarmOutPortNum;// DVR报警输出个数
        public int nDiskNum;// DVR硬盘个数
        public int nDVRType;// DVR类型,见枚举 NET_DEVICE_TYPE
        public int nChanNum;// DVR通道个数
        public byte byLimitLoginTime;// 在线超时时间,为0表示不限制登陆,非0表示限制的分钟数
        public byte byLeftLogTimes;// 当登陆失败原因为密码错误时,通过此参数通知用户,剩余登陆次数,为0时表示此参数无效
        public byte[] bReserved = new byte[2]; // 保留字节,字节对齐
        public int nLockLeftTime;// 当登陆失败,用户解锁剩余时间(秒数), -1表示设备未设置该参数
        public byte[] Reserved = new byte[24];// 保留

        public static class ByReference extends NET_DEVICEINFO_Ex implements Structure.ByReference {
        }

        public static class ByValue extends NET_DEVICEINFO_Ex implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("sSerialNumber");
            a.add("nAlarmInPortNum");
            a.add("nAlarmOutPortNum");
            a.add("nDiskNum");
            a.add("nDVRType");
            a.add("nChanNum");
            a.add("byLimitLoginTime");
            a.add("byLeftLogTimes");
            a.add("bReserved");
            a.add("nLockLeftTime");
            a.add("Reserved");
            return a;
        }
    }

    public static class ST_MSG_OBJECT extends Structure {
        public int nObjectID;                          // 物体ID,每个ID表示一个唯一的物体
        public byte[] szObjectType = new byte[128];                  // 物体类型
        public int nConfidence;                        // 置信度(0~255),值越大表示置信度越高
        public int nAction;                            // 物体动作:1:Appear 2:Move 3:Stay 4:Remove 5:Disappear 6:Split 7:Merge 8:Rename
        public ST_RECT BoundingBox;                        // 包围盒
        public ST_POINT Center;                             // 物体型心
        public int nPolygonNum;                        // 多边形顶点个数
        public ST_POINT[] Contour = new ST_POINT[ST_MAX_POLYGON_NUM];        // 较精确的轮廓多边形
        public int rgbaMainColor;                      // 表示车牌、车身等物体主要颜色;按字节表示,分别为红、绿、蓝和透明度,例如:RGB值为(0,255,0),透明度为0时, 其值为0x00ff0000.
        public byte[] szText = new byte[124];                        // 物体上相关的带0结束符文本,比如车牌,集装箱号等等
        public byte[] szObjectSubType = new byte[62];                // 物体子类别,根据不同的物体类型,可以取以下子类型:
        // Vehicle Category:"Unknown"  未知,"Motor" 机动车,"Non-Motor":非机动车,"Bus": 公交车,"Bicycle" 自行车,"Motorcycle":摩托车,"PassengerCar":客车,
        // "LargeTruck":大货车,    "MidTruck":中货车,"SaloonCar":轿车,"Microbus":面包车,"MicroTruck":小货车,"Tricycle":三轮车,    "Passerby":行人
        //  Plate Category:"Unknown" 未知,"Normal" 蓝牌黑牌,"Yellow" 黄牌,"DoubleYellow" 双层黄尾牌,"Police" 警牌"Armed" 武警牌,
        // "Military" 部队号牌,"DoubleMilitary" 部队双层,"SAR" 港澳特区号牌,"Trainning" 教练车号牌
        // "Personal" 个性号牌,"Agri" 农用牌,"Embassy" 使馆号牌,"Moto" 摩托车号牌,"Tractor" 拖拉机号牌,"Other" 其他号牌
        // "Civilaviation"民航号牌,"Black"黑牌
        // "PureNewEnergyMicroCar"纯电动新能源小车,"MixedNewEnergyMicroCar,"混合新能源小车,"PureNewEnergyLargeCar",纯电动新能源大车
        // "MixedNewEnergyLargeCar"混合新能源大车
        // HumanFace Category:"Normal" 普通人脸,"HideEye" 眼部遮挡,"HideNose" 鼻子遮挡,"HideMouth" 嘴部遮挡,"TankCar"槽罐车(装化学药品、危险品)


        public short wColorLogoIndex;                    // 车标索引
        public short wSubBrand;                          // 车辆子品牌 需要通过映射表得到真正的子品牌 映射表详见开发手册
        public byte byReserved1;
        public /*boolean*/ boolean bPicEnble;                          // 是否有物体对应图片文件信息 TODO
        public ST_PIC_INFO stPicInfo;                          // 物体对应图片信息
        public /*boolean*/ boolean bShotFrame;                         // 是否是抓拍张的识别结果
        public /*boolean*/ boolean bColor;                             // 物体颜色(rgbaMainColor)是否可用
        public byte byReserved2;
        public byte byTimeType;                         // 时间表示类型,详见EM_TIME_TYPE说明
        public NET_TIME_EX stuCurrentTime;                     // 针对视频浓缩,当前时间戳(物体抓拍或识别时,会将此识别智能帧附在一个视频帧或jpeg图片中,此帧所在原始视频中的出现时间)
        public NET_TIME_EX stuStartTime;                       // 开始时间戳(物体开始出现时)
        public NET_TIME_EX stuEndTime;                         // 结束时间戳(物体最后出现时)
        public ST_RECT stuOriginalBoundingBox;             // 包围盒(绝对坐标)
        public ST_RECT stuSignBoundingBox;                 // 车标坐标包围盒

        /* public int dwCurrentSequence;                  // 当前帧序号(抓下这个物体时的帧)
         public int dwBeginSequence;                    // 开始帧序号(物体开始出现时的帧序号)
         public int dwEndSequence;                      // 结束帧序号(物体消逝时的帧序号)
         public int nBeginFileOffset;                   // 开始时文件偏移, 单位: 字节(物体开始出现时,视频帧在原始视频文件中相对于文件起始处的偏移)TODO
         public long nEndFileOffset;                     // 结束时文件偏移, 单位: 字节(物体消逝时,视频帧在原始视频文件中相对于文件起始处的偏移)TODO
         public byte[] byColorSimilar = new byte[8]; // 物体颜色相似度,取值范围:0-100,数组下标值代表某种颜色,详见EM_COLOR_TYPE
         public byte[] byUpperBodyColorSimilar = new byte[8]; // 上半身物体颜色相似度(物体类型为人时有效)
         public byte[] byLowerBodyColorSimilar = new byte[8]; // 下半身物体颜色相似度(物体类型为人时有效)
         public int nRelativeID;                        // 相关物体ID
         public byte[] szSubText = new byte[20];                      // "ObjectType"为"Vehicle"或者"Logo"时,表示车标下的某一车系,比如奥迪A6L,由于车系较多,SDK实现时透传此字段,设备如实填写。
         public short wBrandYear;                         // 车辆品牌年款 需要通过映射表得到真正的年款 映射表详见开发手册
 */
        public static class ByReference extends ST_MSG_OBJECT implements Structure.ByReference {
        }

        public static class ByValue extends ST_MSG_OBJECT implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            //a.add("dwSize");
            a.add("nObjectID");
            a.add("szObjectType");
            a.add("nConfidence");
            a.add("nAction");
            a.add("BoundingBox");
            a.add("Center");
            a.add("nPolygonNum");
            a.add("Contour");
            a.add("rgbaMainColor");
            a.add("szText");
            a.add("szObjectSubType");
            a.add("wColorLogoIndex");
            a.add("wSubBrand");
            a.add("byReserved1");
            a.add("bPicEnble");
            a.add("stPicInfo");
            a.add("bShotFrame");
            a.add("bColor");
            a.add("byReserved2");
            a.add("byTimeType");
            a.add("stuCurrentTime");
            a.add("stuStartTime");
            a.add("stuEndTime");
            a.add("stuOriginalBoundingBox");
            a.add("stuSignBoundingBox");
            /*a.add("dwCurrentSequence");
            a.add("dwBeginSequence");
            a.add("dwEndSequence");
            a.add("nBeginFileOffset");
            a.add("nEndFileOffset");
            a.add("byColorSimilar");
            a.add("byUpperBodyColorSimilar");
            a.add("byLowerBodyColorSimilar");
            a.add("nRelativeID");
            a.add("szSubText");
            a.add("wBrandYear");*/
            return a;
        }
    }

    public static class NET_TIME_EX extends Structure {
        public int dwYear;                  // 年
        public int dwMonth;                 // 月
        public int dwDay;                   // 日
        public int dwHour;                  // 时
        public int dwMinute;                // 分
        public int dwSecond;                // 秒
        public int dwMillisecond;           // 毫秒
        public int[] dwReserved = new int[2];           // 保留字段

        public static class ByReference extends NET_TIME_EX implements Structure.ByReference {
        }

        public static class ByValue extends NET_TIME_EX implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("dwYear");
            a.add("dwMonth");
            a.add("dwDay");
            a.add("dwHour");
            a.add("dwMinute");
            a.add("dwSecond");
            a.add("dwMillisecond");
            a.add("dwReserved");
            return a;
        }
    }

    public static class NET_TIME extends Structure {
        public int dwYear;                  // 年
        public int dwMonth;                 // 月
        public int dwDay;                   // 日
        public int dwHour;                  // 时
        public int dwMinute;                // 分
        public int dwSecond;                // 秒

        public static class ByReference extends NET_TIME_EX implements Structure.ByReference {
        }

        public static class ByValue extends NET_TIME_EX implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("dwYear");
            a.add("dwMonth");
            a.add("dwDay");
            a.add("dwHour");
            a.add("dwMinute");
            a.add("dwSecond");
            return a;
        }
    }

    public static class ST_RECT extends Structure {
        public NativeLong left;
        public NativeLong top;
        public NativeLong right;
        public NativeLong bottom;

        public static class ByReference extends ST_RECT implements Structure.ByReference {
        }

        public static class ByValue extends ST_RECT implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("left");
            a.add("top");
            a.add("right");
            a.add("bottom");
            return a;
        }
    }

    public static class FACERECOGNITION_PERSON_INFOEX extends Structure {
        public byte[] szPersonName = new byte[ST_MAX_PERSON_NAME_LEN];           // 姓名
        public short wYear;                                          // 出生年,作为查询条件时,此参数填0,则表示此参数无效
        public byte byMonth;                                        // 出生月,作为查询条件时,此参数填0,则表示此参数无效
        public byte byDay;                                          // 出生日,作为查询条件时,此参数填0,则表示此参数无效
        public byte bImportantRank;                                 // 人员重要等级,1~10,数值越高越重要,作为查询条件时,此参数填0,则表示此参数无效
        public byte bySex;                                          // 性别,1-男,2-女,作为查询条件时,此参数填0,则表示此参数无效
        public byte[] szID = new byte[ST_MAX_PERSON_ID_LEN];                     // 人员唯一标示(身份证号码,工号,或其他编号)
        public short wFacePicNum;                                    // 图片张数
        public ST_PIC_INFO[] szFacePicInfo = new ST_PIC_INFO[ST_MAX_PERSON_IMAGE_NUM];         // 当前人员对应的图片信息
        public byte byType;                                         // 人员类型,详见 EM_PERSON_TYPE
        public byte byIDType;                                       // 证件类型,详见 EM_CERTIFICATE_TYPE
        public byte byGlasses;                                        // 是否戴眼镜,0-未知 1-不戴 2-戴
        public byte byAge;                                            // 年龄,0表示未知
        public byte[] szProvince = new byte[ST_MAX_PROVINCE_NAME_LEN];           // 省份
        public byte[] szCity = new byte[ST_MAX_CITY_NAME_LEN];                   // 城市
        public byte[] szUID = new byte[ST_MAX_PERSON_ID_LEN];                    // 人员唯一标识符,首次由服务端生成,区别于ID字段
        // 修改,删除操作时必填
        public byte[] szCountry = new byte[NET_COUNTRY_LENGTH];               // 国籍,符合ISO3166规范
        public byte byIsCustomType;                                    // 人员类型是否为自定义: 0 使用Type规定的类型 1 自定义,使用szCustomType字段
        public byte[] szCustomType = new byte[ST_COMMON_STRING_16];         // 人员自定义类型
        public byte[] szComment = new byte[NET_COMMENT_LENGTH];                    // 备注信息
        public byte[] szGroupID = new byte[NET_GROUPID_LENGTH];                    // 人员所属组ID
        public byte[] szGroupName = new byte[NET_GROUPNAME_LENGTH];                // 人员所属组名, 用户自己申请内存的情况时,
        public byte emEmotion;                            // 表情
        public byte[] szHomeAddress = new byte[ST_COMMON_STRING_128];            // 注册人员家庭地址
        public byte emGlassesType;                                    // 眼镜类型
        public byte emRace;                                            // 种族
        public byte emEye;                                            // 眼睛状态
        public byte emMouth;                                        // 嘴巴状态
        public byte emMask;                                            // 口罩状态
        public byte emBeard;                                        // 胡子状态
        public int nAttractive;                                    // 魅力值, -1表示无效, 0未识别,识别时范围1-100,得分高魅力高
        public byte emFeatureState;                                    // 人员建模状态
        public byte[] byReserved = new byte[2044];                            // 保留字节

        public static class ByReference extends FACERECOGNITION_PERSON_INFOEX implements Structure.ByReference {
        }

        public static class ByValue extends FACERECOGNITION_PERSON_INFOEX implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("szPersonName");
            a.add("wYear");
            a.add("byMonth");
            a.add("byDay");
            a.add("bImportantRank");
            a.add("bySex");
            a.add("szID");
            a.add("wFacePicNum");
            a.add("szFacePicInfo");
            a.add("byType");
            a.add("byIDType");
            a.add("byGlasses");
            a.add("byAge");
            a.add("szProvince");
            a.add("szCity");
            a.add("szUID");
            a.add("szCountry");
            a.add("byIsCustomType");
            a.add("szCustomType");
            a.add("szComment");
            a.add("szGroupID");
            a.add("szGroupName");
            a.add("emEmotion");
            a.add("szHomeAddress");
            a.add("emGlassesType");
            a.add("emRace");
            a.add("emEye");
            a.add("emMouth");
            a.add("emMask");
            a.add("emBeard");
            a.add("nAttractive");
            a.add("emFeatureState");
            a.add("byReserved");
            return a;
        }
    }

    public static class EVENT_INTELLI_COMM_INFO extends Structure {
        public byte emClassType;                                // 智能事件所属大类
        public int nPresetID;                                    // 该事件触发的预置点,对应该设置规则的预置点
        public byte[] bReserved = new byte[124];                            // 保留字节,留待扩展.

        public static class ByReference extends EVENT_INTELLI_COMM_INFO implements Structure.ByReference {
        }

        public static class ByValue extends EVENT_INTELLI_COMM_INFO implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("emClassType");
            a.add("nPresetID");
            a.add("bReserved");
            return a;
        }
    }

    public static class ST_PIC_INFO_EX3 extends Structure {
        public int dwOffSet;                       // 文件在二进制数据块中的偏移位置, 单位:字节
        public int dwFileLenth;                    // 文件大小, 单位:字节
        public short wWidth;                         // 图片宽度, 单位:像素
        public short wHeight;                        // 图片高度, 单位:像素
        public byte[] szFilePath = new byte[64];                 // 文件路径
        public byte bIsDetected;                    // 图片是否算法检测出来的检测过的提交识别服务器时,
        // 则不需要再时检测定位抠图,1:检测过的,0:没有检测过
        public byte[] bReserved = new byte[11];                  // 保留

        public static class ByReference extends ST_PIC_INFO_EX3 implements Structure.ByReference {
        }

        public static class ByValue extends ST_PIC_INFO_EX3 implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("dwOffSet");
            a.add("dwFileLenth");
            a.add("wWidth");
            a.add("wHeight");
            a.add("szFilePath");
            a.add("bIsDetected");
            a.add("bReserved");
            return a;
        }
    }

    public static class ST_POINT extends Structure {
        public short nx;
        public short ny;

        public static class ByReference extends ST_POINT implements Structure.ByReference {
        }

        public static class ByValue extends ST_POINT implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("nx");
            a.add("ny");
            return a;
        }
    }

    public static class ST_PIC_INFO extends Structure {
        public int dwOffSet;                       // 文件在二进制数据块中的偏移位置, 单位:字节
        public int dwFileLenth;                    // 文件大小, 单位:字节
        public short wWidth;                         // 图片宽度, 单位:像素
        public short wHeight;                        // 图片高度, 单位:像素
        public Pointer pszFilePath;                    // 鉴于历史原因,该成员只在事件上报时有效
        // 文件路径
        // 用户使用该字段时需要自行申请空间进行拷贝保存
        public byte bIsDetected;                    //图片是否算法检测出来的检测过的提交识别服务器时,
        //则不需要再时检测定位抠图,1:检测过的,0:没有检测过

        public byte[] bReserved = new byte[7];                   // 12<--16
        public ST_POINT stuPoint;                        // 小图左上角在大图的位置,使用绝对坐标系


        public static class ByReference extends ST_PIC_INFO implements Structure.ByReference {
        }

        public static class ByValue extends ST_PIC_INFO implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("dwOffSet");
            a.add("dwFileLenth");
            a.add("wWidth");
            a.add("wHeight");
            a.add("pszFilePath");
            a.add("bIsDetected");
            a.add("bReserved");
            a.add("stuPoint");
            return a;
        }
    }

    public static class FACERECOGNITION_PERSON_INFO extends Structure {
        public byte[] szPersonName = new byte[ST_MAX_NAME_LEN];                  // 姓名,此参数作废
        public int wYear;                                          // 出生年,作为查询条件时,此参数填0,则表示此参数无效
        public byte byMonth;                                        // 出生月,作为查询条件时,此参数填0,则表示此参数无效
        public byte byDay;                                          // 出生日,作为查询条件时,此参数填0,则表示此参数无效
        public byte[] szID = new byte[ST_MAX_PERSON_ID_LEN];                     // 人员唯一标示(身份证号码,工号,或其他编号)
        public byte bImportantRank;                                 // 人员重要等级,1~10,数值越高越重要,作为查询条件时,此参数填0,则表示此参数无效
        public byte bySex;                                          // 性别,1-男,2-女,作为查询条件时,此参数填0,则表示此参数无效
        public short wFacePicNum;                                    // 图片张数
        public ST_PIC_INFO[] szFacePicInfo = new ST_PIC_INFO[ST_MAX_PERSON_IMAGE_NUM];         // 当前人员对应的图片信息
        public byte byType;                                         // 人员类型,详见 EM_PERSON_TYPE
        public byte byIDType;                                       // 证件类型,详见 EM_CERTIFICATE_TYPE
        public byte byGlasses;                                        // 是否戴眼镜,0-未知 1-不戴 2-戴
        public byte byAge;                                            // 年龄,0表示未知
        public byte[] szProvince = new byte[ST_MAX_PROVINCE_NAME_LEN];           // 省份
        public byte[] szCity = new byte[ST_MAX_CITY_NAME_LEN];                   // 城市
        public byte[] szPersonNameEx = new byte[ST_MAX_PERSON_NAME_LEN];         // 姓名,因存在姓名过长,16字节无法存放问题,故增加此参数,
        public byte[] szUID = new byte[ST_MAX_PERSON_ID_LEN];                    // 人员唯一标识符,首次由服务端生成,区别于ID字段
        // 修改,删除操作时必填
        public byte[] szCountry = new byte[NET_COUNTRY_LENGTH];                    // 国籍,符合ISO3166规范
        public byte byIsCustomType;                                    // 人员类型是否为自定义: 0 使用Type规定的类型 1 自定义,使用szPersonName字段
        public Pointer pszComment;                                    // 备注信息, 用户自己申请内存的情况时,
        // 下方bCommentLen需填写对应的具体长度值,推荐长度 NET_COMMENT_LENGTH

        public Pointer pszGroupID;                                    // 人员所属组ID, 用户自己申请内存的情况时,
        // 下方bGroupIdLen需填写对应的具体长度值,推荐长度 NET_GROUPID_LENGTH

        public Pointer pszGroupName;                                    // 人员所属组名, 用户自己申请内存的情况时,
        // 下方bGroupNameLen需填写对应的具体长度值,推荐长度 NET_GROUPNAME_LENGTH

        public Pointer pszFeatureValue;                                // 人脸特征, 用户自己申请内存的情况时,
        // 下方bFeatureValueLen需填写对应的具体长度值,推荐长度 NET_FEATUREVALUE_LENGTH

        public byte bGroupIdLen;                                    // pszGroupID的长度
        public byte bGroupNameLen;                                    // pszGroupName的长度
        public byte bFeatureValueLen;                                // pszFeatureValue的长度
        public byte bCommentLen;                                    // pszComment的长度
        public byte emEmotion;                    // 表情


        public static class ByReference extends FACERECOGNITION_PERSON_INFO implements Structure.ByReference {
        }

        public static class ByValue extends FACERECOGNITION_PERSON_INFO implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("szPersonName");
            a.add("wYear");
            a.add("byMonth");
            a.add("byDay");
            a.add("szID");
            a.add("bImportantRank");
            a.add("bySex");
            a.add("wFacePicNum");
            a.add("szFacePicInfo");
            a.add("byType");
            a.add("byIDType");
            a.add("byGlasses");
            a.add("byAge");
            a.add("szProvince");
            a.add("szCity");
            a.add("szPersonNameEx");
            a.add("szUID");
            a.add("szCountry");
            a.add("byIsCustomType");
            a.add("pszComment");
            a.add("pszGroupID");
            a.add("pszGroupName");
            a.add("pszFeatureValue");
            a.add("bGroupIdLen");
            a.add("bGroupNameLen");
            a.add("bFeatureValueLen");
            a.add("bCommentLen");
            a.add("emEmotion");
            return a;
        }
    }

    public static class CANDIDATE_INFO extends Structure {
        public FACERECOGNITION_PERSON_INFO stPersonInfo;            // 人员信息
        // 布控(黑名单)库,指布控库中人员信息;
        // 历史库,指历史库中人员信息
        // 报警库,指布控库的人员信息

        public byte bySimilarity;            // 和查询图片的相似度,百分比表示,1~100
        public byte byRange;                 // 人员所属数据库范围,详见EM_FACE_DB_TYPE
        public byte byReserved1;
        public NET_TIME stTime;                  // 当byRange为历史数据库时有效,表示查询人员出现的时间
        public byte[] szAddress = new byte[MAX_PATH];     // 当byRange为历史数据库时有效,表示查询人员出现的地点
        public boolean bIsHit;                  // 是否有识别结果,指这个检测出的人脸在库中有没有比对结果
        public ST_PIC_INFO_EX3 stuSceneImage;           // 人脸全景图
        public int nChannelID;              // 通道号
        public byte[] byReserved = new byte[32];          // 保留字节


        public static class ByReference extends CANDIDATE_INFO implements Structure.ByReference {
        }

        public static class ByValue extends CANDIDATE_INFO implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("stPersonInfo");
            a.add("bySimilarity");
            a.add("byRange");
            a.add("byReserved1");
            a.add("stTime");
            a.add("szAddress");
            a.add("bIsHit");
            a.add("stuSceneImage");
            a.add("nChannelID");
            a.add("byReserved");
            return a;
        }
    }

    public static class DEV_EVENT_FACERECOGNITION_INFO extends Structure {
        public int nChannelID;                                 // 通道号
        public byte[] szName = new byte[128];                                // 事件名称
        public int nEventID;                                   // 事件ID
        public NET_TIME_EX UTC;                                        // 事件发生的时间
        public ST_MSG_OBJECT stuObject;                                  // 检测到的物体
        public int nCandidateNum;                              // 当前人脸匹配到的候选对象数量
        public CANDIDATE_INFO[] stuCandidates = new CANDIDATE_INFO[ST_MAX_CANDIDATE_NUM];        // 当前人脸匹配到的候选对象信息
        public byte bEventAction;                               // 事件动作,0表示脉冲事件,1表示持续性事件开始,2表示持续性事件结束;
        public byte byImageIndex;                               // 图片的序号, 同一时间内(精确到秒)可能有多张图片, 从0开始
        public byte[] byReserved1 = new byte[51];                             // 对齐
        public /*boolean*/ boolean bGlobalScenePic;                            // 全景图是否存在
        public ST_PIC_INFO stuGlobalScenePicInfo;                      // 全景图片信息
        //public byte[] szSnapDevAddress = new byte[MAX_PATH];                 // 抓拍当前人脸的设备地址,如:滨康路37号
        public int nOccurrenceCount;                           // 事件触发累计次数 TODO
        //public EVENT_INTELLI_COMM_INFO stuIntelliCommInfo;                 // 智能事件公共信息
        public NET_FACE_DATA stuFaceData;                                // 人脸数据
        /*public char szUID;                    // 抓拍人员写入数据库的唯一标识符
        public int bReserved;                            // 保留字节,留待扩展.
        public int nRetCandidatesExNum;                        // 当前人脸匹配到的候选对象数量实际返回值
        public CANDIDATE_INFOEX stuCandidatesEx;     // 当前人脸匹配到的候选对象信息扩展*/

        public static class ByReference extends DEV_EVENT_FACERECOGNITION_INFO implements Structure.ByReference {
        }

        public static class ByValue extends DEV_EVENT_FACERECOGNITION_INFO implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("nChannelID");
            a.add("szName");
            a.add("nEventID");
            a.add("UTC");
            a.add("stuObject");
            a.add("nCandidateNum");
            a.add("stuCandidates");
            a.add("bEventAction");
            a.add("byImageIndex");
            a.add("byReserved1");
            a.add("bGlobalScenePic");
            a.add("stuGlobalScenePicInfo");
            //a.add("szSnapDevAddress");
            a.add("nOccurrenceCount");
            //a.add("stuIntelliCommInfo");
            a.add("stuFaceData");
            /*a.add("szUID");
            a.add("bReserved");
            a.add("nRetCandidatesExNum");
            a.add("stuCandidatesEx");*/
            return a;
        }
    }

    public static class NET_FACE_DATA extends Structure {
        public byte emSex;                        // 性别
        public int nAge;                        // 年龄,-1表示该字段数据无效
        public int nFeatureValidNum;           // 人脸特征数组有效个数,与 emFeature 结合使用
        public byte emFeature;   // 人脸特征数组,与 nFeatureValidNum 结合使用
        public byte emRace;                        // 种族
        public byte emEye;                        // 眼睛状态
        public byte emMouth;                    // 嘴巴状态
        public byte emMask;                        // 口罩状态
        public byte emBeard;                    // 胡子状态
        public int nAttractive;                // 魅力值, -1表示无效, 0未识别,识别时范围1-100,得分高魅力高
        public byte[] bReserved = new byte[128];             // 保留字节,留待扩展.


        public static class ByReference extends NET_FACE_DATA implements Structure.ByReference {
        }

        public static class ByValue extends NET_FACE_DATA implements Structure.ByValue {
        }

        @SuppressWarnings({"rawtypes", "unchecked"})
        @Override
        protected List getFieldOrder() {
            List a = new ArrayList();
            a.add("emSex");
            a.add("nAge");
            a.add("nFeatureValidNum");
            a.add("emFeature");
            a.add("emRace");
            a.add("emEye");
            a.add("emMouth");
            a.add("emMask");
            a.add("emBeard");
            a.add("nAttractive");
            a.add("bReserved");
            return a;
        }
    }

    public static final int EVENT_IVS_ALL = 0x00000001;//订阅所有事件
    public static final int EVENT_IVS_FACEDETECT = 0x0000001A;//人脸检测事件 (对应 DEV_EVENT_FACEDETECT_INFO)
    public static final int EVENT_IVS_FACERECOGNITION = 0x00000117;//人脸识别事件(对应 DEV_EVENT_FACERECOGNITION_INFO)

    public interface Dll extends Library {
        Dll instance = (Dll) Native.loadLibrary("stnetsdk", Dll.class);

        /**
         * 初始化方法
         */
        void CLIENT_Init();

        /**
         * 清除资源
         */
        void CLIENT_Cleanup();

        /**
         * 获取版本
         *
         * @return
         */
        int CLIENT_GetSDKVersion();

        /**
         * 设置断线重连成功回调函数接口,设置后 SDK 内部检测到设备断线则进行自动重连。
         *
         * @param cbAutoConnect
         * @param dwUser
         */
        void CLIENT_SetAutoReconnect(HaveReConnectCallBack cbAutoConnect, int dwUser);

        /**
         * 设置连接设备超时时间和尝试次数接口。
         *
         * @param nWaitTime 每次登录时,等待设备响应超时时间
         * @param nTryTimes 每次登录时,连接尝试登录设备次数。
         */
        void CLIENT_SetConnectTime(int nWaitTime, int nTryTimes);

        Long CLIENT_LoginEx2(final String pchDVRIP, int wDVRPort, final String pchUserName, final String pchPassword, int EM_LOGIN_SPEC_CAP_TCP, String pCapParam, NET_DEVICEINFO_Ex lpDeviceInfo, int error);

        /**
         * 错误代码回调
         *
         * @return
         */
        Long CLIENT_GetLastError();

        /**
         * 智能图片报警订阅接口
         *
         * @param lLoginID         登陆设备id
         * @param nChannelID       智能图片报警订阅通道号,通道号从 0 开始
         * @param dwAlarmType      期望订阅的报警类型   如:EVENT_IVS_ALL //所有报警信息都会上传
         * @param bNeedPicFile     是否订阅图片文件    TRUE:表示订阅图片文件,在回调函数中会返回智能图片信息 FALSE:表示不订阅图片文件,在回调函数中不会返回智能图片信息(在不
         *                         需要图片信息时,可减少网络流量)
         * @param //cbAnalyzerData 智能图片报警回调函数
         * @param dwUser           用户数据,SDK 通过智能图片报警回调函数 fAnalyzerDataCallBack将该数据返回给用户,以便用户后续操作
         * @param pointer          保留参数   该字段建议填 NULL
         * @return
         */
        Long CLIENT_RealLoadPictureEx(Long lLoginID, int nChannelID, int dwAlarmType, boolean bNeedPicFile, fAnalyzerDataCallBack analyzerDataCallBack, int dwUser, Pointer pointer);

        /**
         * 主动注册功能-开启服务监听
         *
         * @param ip         服务器ip
         * @param port       端口
         * @param nTimeout
         * @param cbListen   回调函数
         * @param dwUserData
         * @return
         */
        Long CLIENT_ListenServer(String ip, int port, int nTimeout, ServiceCallBackCallBack cbListen, Long dwUserData);
    }

    /**
     * 获取人脸识别的回调函数接口
     */
    public interface fAnalyzerDataCallBack extends Callback {
        int fAnalyzerDataCallBack(Long lAnalyzerHandle, int dwAlarmType,
                                  Pointer pAlarmInfo, String pBuffer, int dwBufSize, Long dwUser, int nSequence,
                                  Pointer reserved);
    }

    /**
     * 断线重连回调函数
     */
    public interface HaveReConnectCallBack extends Callback {
        int HaveReConnect(long lLoginID, String pchDVRIP, long nDVRPort, long dwUser);
    }

    /**
     * 主动注册回调函数
     */
    public interface ServiceCallBackCallBack extends Callback {
        int ServiceCallBack(long lHandle, String pIp, short wPort, long lCommand, String pParam, int dwParamLen, Long dwUserData);
    }


    /**
     * 获取人脸识别的回调函数接口实现类
     */
    static class fAnalyzerDataCallBackImpl implements fAnalyzerDataCallBack {

        @Override
        public int fAnalyzerDataCallBack(Long lAnalyzerHandle, int dwAlarmType, Pointer pAlarmInfo, String pBuffer, int dwBufSize, Long dwUser
                , int nSequence, Pointer reserved) {
            //实时人脸抓拍上传
            DEV_EVENT_FACERECOGNITION_INFO strFaceSnapInfo = new DEV_EVENT_FACERECOGNITION_INFO();
            strFaceSnapInfo.write();
            Pointer pFaceSnapInfo = strFaceSnapInfo.getPointer();
            pFaceSnapInfo.write(0, pAlarmInfo.getByteArray(0, strFaceSnapInfo.size()), 0, strFaceSnapInfo.size());
            strFaceSnapInfo.read();
            log.info("strFaceSnapInfo = " + strFaceSnapInfo);

            String sex = "";
            if (1 == strFaceSnapInfo.stuFaceData.emSex) {
                sex = "男";
            } else if (2 == strFaceSnapInfo.stuFaceData.emSex) {
                sex = "女";
            } else {
                sex = "未知";
            }

            String sAlarmType = "事件名称:" + new String(strFaceSnapInfo.szName) +
                    " 年龄:" + strFaceSnapInfo.stuFaceData.nAge + ",性别:" + sex;
            log.info("sAlarmType = " + sAlarmType);

            HumanFactory.createHuman(strFaceSnapInfo.stuFaceData.emSex, strFaceSnapInfo.stuFaceData.nAge, dvrCode);
            return 1;
        }
    }

    static class HaveReConnectCallBackImpl implements HaveReConnectCallBack {

        @Override
        public int HaveReConnect(long lLoginID, String pchDVRIP, long nDVRPort, long dwUser) {
            log.info("断线(断网)重连回调函数:lLoginID = [" + lLoginID + "], pchDVRIP = [" + pchDVRIP + "], nDVRPort = [" + nDVRPort + "], dwUser = [" + dwUser + "]");
            return 0;
        }
    }

    static class ServiceCallBackCallBackImpl implements ServiceCallBackCallBack {
        @Override
        public int ServiceCallBack(long lHandle, String pIp, short wPort, long lCommand, String pParam, int dwParamLen, Long dwUserData) {
            System.err.println("断电回调函数:lHandle = [" + lHandle + "], pIp = [" + pIp + "], wPort = [" + wPort + "], lCommand = [" + lCommand + "], pParam = [" + pParam + "], dwParamLen = [" + dwParamLen + "], dwUserData = [" + dwUserData + "]");
            if (1 == lCommand) {
                int nError = 0;
                NET_DEVICEINFO_Ex stDevInfo = new NET_DEVICEINFO_Ex();
                long loginId = Dll.instance.CLIENT_LoginEx2(pIp, wPort, "admin", "admin", 2, pParam, stDevInfo, nError);
            }
            return 0;
        }
    }

    /**
     * 初始化
     */
    private static STNetSDK.HaveReConnectCallBack haveReConnectCallBack = new STNetSDK.HaveReConnectCallBackImpl();

    public static void init() {
        //初始化
        Dll.instance.CLIENT_Init();

        //获取版本
        int s = Dll.instance.CLIENT_GetSDKVersion();
        log.info("NetSDK version is " + s);

        //设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作。
        Dll.instance.CLIENT_SetAutoReconnect(haveReConnectCallBack, 0);

        //设置连接设备超时时间和尝试次数
        Dll.instance.CLIENT_SetConnectTime(500, 3);

        //释放资源
        //Dll.instance.CLIENT_Cleanup();
    }

    /**
     * 登陆功能--------------Begin------------------------
     */
    private static STNetSDK.fAnalyzerDataCallBack fanalyzerDataCallBack = new STNetSDK.fAnalyzerDataCallBackImpl();
    private static STNetSDK.ServiceCallBackCallBack serviceCallBackCallBack = new STNetSDK.ServiceCallBackCallBackImpl();

    /**
     * 登陆
     *
     * @param dvrIp
     * @param dvrPort
     * @param dvr_loginName
     * @param dvr_loginPassword
     */
    public static Long login(String dvrIp, int dvrPort, String dvr_loginName, String dvr_loginPassword) {
        //初始化
        init();
        NET_DEVICEINFO_Ex net_deviceinfo_ex = new NET_DEVICEINFO_Ex();

        Long loginId = Dll.instance.CLIENT_LoginEx2(dvrIp, dvrPort, dvr_loginName, dvr_loginPassword, 0, null, net_deviceinfo_ex, 0);
        log.info("loginId = " + loginId);
        log.info("net_deviceinfo_ex = " + net_deviceinfo_ex);
        dvrCode = new String(net_deviceinfo_ex.sSerialNumber);
        dvrService.insertDvr(String.valueOf(loginId), dvrIp, dvrCode);

        if (0 == loginId) {
            Long error = Dll.instance.CLIENT_GetLastError();
            System.err.println("loginIdError = " + error);
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Long aLong = Dll.instance.CLIENT_ListenServer("192.168.1.183", 6060, 0, serviceCallBackCallBack, null);
        System.out.println("aLong = " + aLong);
        return loginId;
    }

    /**
     * 抓取回调函数里面的数据
     *
     * @throws InterruptedException
     */
    private static String dvrCode;
    public static void FetchingData(String dvrIp, int dvrPort, String dvr_loginName, String dvr_loginPassword) throws InterruptedException {
        //登陆
        Long loginId = login(dvrIp, dvrPort, dvr_loginName, dvr_loginPassword);

        //抓取数据
        Long dataId = Dll.instance.CLIENT_RealLoadPictureEx(loginId, 0, EVENT_IVS_FACERECOGNITION, true, fanalyzerDataCallBack, 0, null);

        if (0 == dataId) {
            Long dataIdError = Dll.instance.CLIENT_GetLastError();
            System.err.println("dataIdError = " + dataIdError);
        }

        //释放资源
        // Dll.instance.CLIENT_Cleanup();
    }
}
           

继续阅读