天天看點

對接商湯攝像頭詳細步驟準備工作

對接商湯攝像頭詳細步驟

    • 已實作接口
  • 準備工作
    • 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();
    }
}
           

繼續閱讀