美文网首页
Java调用海康sdk操作热成像设备获取对应点温度

Java调用海康sdk操作热成像设备获取对应点温度

作者: 叁太紫 | 来源:发表于2021-03-26 17:12 被阅读0次

    Java调用海康sdk操作热成像设备获取对应点温度, 海康官方提供有Java版的sdk,遗憾的是里面提供的api比较旧了新版的api需要根据c++版的开发文档自己写对应的java接口和类。这对于不熟悉c++的开发人员比较吃力。下面的代码示例了通过海康的SDK获取热成像画面上某一点的具体温度。目前已经使用Python实现了相应的效果,有需要Python版本的可以留言。
    maven依赖

            <dependency>
                <groupId>com.sun.jna</groupId>
                <artifactId>jna</artifactId>
                <version>3.0.9</version>
            </dependency>
    
    import com.sun.jna.Native;
    import com.sun.jna.NativeLong;
    import lombok.extern.slf4j.Slf4j;
    
    import java.nio.ByteBuffer;
    
    /**
     * 调用demo
     *
     * @author JW
     * @version 1.0
     * @date 2021/3/25 14:47
     */
    @Slf4j
    public class HKNetApp {
    
        private NativeLong lUserID = new NativeLong(-1);//用户句柄
        private HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;//设备信息
    
        static HCNetSDK hCNetSDK = null;//sdk
    
        public static synchronized void loadLibrary(String libraryPath){
            if(null == hCNetSDK){
                hCNetSDK = (HCNetSDK) Native.loadLibrary(libraryPath, HCNetSDK.class);
            }
        }
    
        public static void main(String[] args) {
            loadLibrary("你的sdk地址");
    
            HKNetApp hkNetApp = new HKNetApp();
    
            if (hkNetApp.init() && hkNetApp.login()) {
                Float temperature = hkNetApp.getTemperature(new HKPoint(1,1), 126, 100);
                log.info("1,1点的温度是,{}", temperature);
            }
    
            hkNetApp.logout();
            hCNetSDK.NET_DVR_Cleanup();
        }
    
        /**
         * SDK初始化
         * @return
         */
        public Boolean init() {
            if (!hCNetSDK.NET_DVR_Init()) {
                log.error("初始化失败");
                return false;
            }
            return true;
        }
    
    
        /*************************************************
         函数:      "注册"  按钮单击响应函数
         函数描述:  注册登录设备
         *************************************************/
        public Boolean login() {//GEN-FIRST:event_jButtonLoginActionPerformed
            //注册之前先注销已注册的用户,预览情况下不可注销
            if (lUserID.longValue() > -1) {
                //先注销
                hCNetSDK.NET_DVR_Logout_V30(lUserID);
            }
            //注册
            m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
    
            lUserID = hCNetSDK.NET_DVR_Login_V30("192.168.8.14", (short) 8000, "admin", "a1234567", m_strDeviceInfo);
    
            long userID = lUserID.longValue();
            boolean initSuc = hCNetSDK.NET_DVR_SetLogToFile(3, "f:\\sdklog\\", false);
    
            if (userID == -1) {
                log.error("登录失败,{}", userID);
                return false;
            }
            return true;
        }
    
        public void logout() {
            hCNetSDK.NET_DVR_Logout_V30(lUserID);
        }
    
        public Float getTemperature(HKPoint hkPoint, int sourceWidth, int sourceHeight) {
            boolean bRet = false;
            int nErr = 0;
            int erro;
            HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO m_struThermometryInfo = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO();
            m_struThermometryInfo.dwSize = m_struThermometryInfo.size();
    
            HCNetSDK.NET_DVR_THERMOMETRY_COND m_struThermometryCond = new HCNetSDK.NET_DVR_THERMOMETRY_COND();
            m_struThermometryCond.dwSize = m_struThermometryCond.size();
            m_struThermometryCond.dwChannel = 1;
            m_struThermometryCond.wPresetNo = 1;
            m_struThermometryCond.write();
    
            HCNetSDK.NET_DVR_STD_CONFIG struCfg = new HCNetSDK.NET_DVR_STD_CONFIG();
            struCfg.lpCondBuffer = m_struThermometryCond.getPointer();
            struCfg.dwCondSize = m_struThermometryCond.size();
            struCfg.lpOutBuffer = m_struThermometryInfo.getPointer();
            struCfg.dwOutSize = m_struThermometryInfo.size();
    
            HCNetSDK.BYTE_ARRAY m_szStatusBuf = new HCNetSDK.BYTE_ARRAY(4096 * 4);
            struCfg.lpStatusBuffer = m_szStatusBuf.getPointer();
            struCfg.dwStatusSize = 4096 * 4;
            struCfg.byDataType = 0;
    
            bRet = hCNetSDK.NET_DVR_GetSTDConfig(lUserID, 3624, struCfg);
            if (!bRet) {
                nErr = hCNetSDK.NET_DVR_GetLastError();
                log.error("NET_DVR_GetSTDConfig失败,{}", nErr);
                return 0f;
            }
    
            m_struThermometryInfo.dwSize = m_struThermometryInfo.size();
            m_struThermometryInfo.wPresetNo = 1;
            m_struThermometryInfo.struPresetInfo[0] = new HCNetSDK.NET_DVR_THERMOMETRY_PRESETINFO_PARAM();
            m_struThermometryInfo.struPresetInfo[0].byEnabled = 1;
            m_struThermometryInfo.struPresetInfo[0].byRuleID = 1;
            m_struThermometryInfo.struPresetInfo[0].wDistance = 10;
            m_struThermometryInfo.struPresetInfo[0].fEmissivity = (float) 0.9599;
            m_struThermometryInfo.struPresetInfo[0].byReflectiveEnabled = 0;
            m_struThermometryInfo.struPresetInfo[0].fReflectiveTemperature = 20;
            m_struThermometryInfo.struPresetInfo[0].byRuleCalibType = 2;
            //m_struThermometryInfo.struPresetInfo[0].szRuleName ="1";
            m_struThermometryInfo.struPresetInfo[0].byDistanceUnit = 0;
            //m_struThermometryInfo.struPresetInfo[0].byemissivityMode = 0;
            m_struThermometryInfo.struPresetInfo[0].struPoint = new HCNetSDK.NET_VCA_POINT();
            m_struThermometryInfo.struPresetInfo[0].struPoint.fX = 0;
            m_struThermometryInfo.struPresetInfo[0].struPoint.fY = 0;
            m_struThermometryInfo.struPresetInfo[0].struPoint.write();
            m_struThermometryInfo.struPresetInfo[0].struRegion = new HCNetSDK.NET_VCA_POLYGON();
            m_struThermometryInfo.struPresetInfo[0].struRegion.dwPointNum = 2;
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0] = new HCNetSDK.NET_VCA_POINT();
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fX = (float) 0.187;
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].fY = (float) 0.6119;
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[0].write();
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1] = new HCNetSDK.NET_VCA_POINT();
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fX = (float) 0.876;
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].fY = (float) 0.569;
            m_struThermometryInfo.struPresetInfo[0].struRegion.struPos[1].write();
            m_struThermometryInfo.struPresetInfo[0].struRegion.write();
            m_struThermometryInfo.write();
            struCfg.lpInBuffer = m_struThermometryInfo.getPointer();
            struCfg.dwInSize = m_struThermometryInfo.size();
    
            boolean setSTDConfig = hCNetSDK.NET_DVR_SetSTDConfig(lUserID, 3625, struCfg);
            log.info("NET_DVR_SetSTDConfig,{}", setSTDConfig);
    
            HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA m_strJpegWithAppenData = new HCNetSDK.NET_DVR_JPEGPICTURE_WITH_APPENDDATA();
            m_strJpegWithAppenData.dwSize = m_strJpegWithAppenData.size();
            m_strJpegWithAppenData.dwChannel = 1;
            HCNetSDK.BYTE_ARRAY ptrJpegByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
            HCNetSDK.BYTE_ARRAY ptrP2PDataByte = new HCNetSDK.BYTE_ARRAY(2 * 1024 * 1024);
            m_strJpegWithAppenData.pJpegPicBuff = ptrJpegByte.getPointer();
            m_strJpegWithAppenData.pP2PDataBuff = ptrP2PDataByte.getPointer();
    
    
            bRet = hCNetSDK.NET_DVR_CaptureJPEGPicture_WithAppendData(lUserID, 2, m_strJpegWithAppenData);
            if (bRet) {
                //测温数据
                if (m_strJpegWithAppenData.dwP2PDataLen > 0) {
                    HKPoint point = point2point(hkPoint, sourceWidth, sourceHeight, m_strJpegWithAppenData.dwJpegPicWidth, m_strJpegWithAppenData.dwJpegPicHeight);
                    return getTemperature0(m_strJpegWithAppenData.pP2PDataBuff.getByteBuffer( (m_strJpegWithAppenData.dwJpegPicWidth * point.y  + point.x) * 4, 4));
                }
            }
    
            return 0f;
        }
    
        private Float getTemperature0(ByteBuffer byteBuffer) {
            byte[] byTempData = new byte[4];
            byteBuffer.get(byTempData);
    
            int l = byTempData[0];
            l &= 0xff;
            l |= ((long) byTempData[1] << 8);
            l &= 0xffff;
            l |= ((long) byTempData[2] << 16);
            l &= 0xffffff;
            l |= ((long) byTempData[3] << 24);
    
            return Float.intBitsToFloat(l);
        }
    
        private HKPoint point2point(HKPoint points, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight) {
            points.x = points.x * sourceWidth / targetWidth;
            points.y = points.y * sourceHeight / targetHeight;
    
            points.x = points.x >= targetWidth ? targetWidth : points.x;
            points.x = points.x < 0 ? 0 : points.x;
    
            points.y = points.y >= targetHeight ? targetHeight : points.y;
            points.y = points.y < 0 ? 0 : points.y;
    
            return points;
        }
    }
    

    sdk接口类,因为官方demo代码较多这里只提取了需要使用的部分。

    import com.sun.jna.Native;
    import com.sun.jna.NativeLong;
    import com.sun.jna.Pointer;
    import com.sun.jna.Structure;
    import com.sun.jna.win32.StdCallLibrary;
    
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * 海康sdk调用接口
     */
    public interface HCNetSDK extends StdCallLibrary {
    
        /**
         * 常量
         */
        int SERIALNO_LEN = 48;   //序列号长度
        int NAME_LEN = 32;    //用户名长度
    
        //method
        boolean NET_DVR_Init();
    
        boolean NET_DVR_Cleanup();
    
        NativeLong NET_DVR_Login_V30(String sDVRIP, short wDVRPort, String sUserName, String sPassword, NET_DVR_DEVICEINFO_V30 lpDeviceInfo);
    
        boolean NET_DVR_Logout_V30(NativeLong lUserID);
    
        boolean NET_DVR_SetSTDConfig(NativeLong lUserID, int dwCommand, NET_DVR_STD_CONFIG lpInConfigParam);
    
        boolean NET_DVR_GetSTDConfig(NativeLong lUserID, int dwCommand, NET_DVR_STD_CONFIG lpOutConfigParam);
    
        boolean NET_DVR_CaptureJPEGPicture_WithAppendData(NativeLong lUserID, int lChannel, NET_DVR_JPEGPICTURE_WITH_APPENDDATA lpJpegWithAppend);
    
        int NET_DVR_GetLastError();
    
        //启用日志文件写入接口
        boolean NET_DVR_SetLogToFile(int bLogEnable, String strLogDir, boolean bAutoDel);
    
        //NET_DVR_Login_V30()参数结构
        class NET_DVR_DEVICEINFO_V30 extends Structure {
            public byte[] sSerialNumber = new byte[SERIALNO_LEN];  //序列号
            public byte byAlarmInPortNum;                //报警输入个数
            public byte byAlarmOutPortNum;                //报警输出个数
            public byte byDiskNum;                    //硬盘个数
            public byte byDVRType;                    //设备类型, 1:DVR 2:ATM DVR 3:DVS ......
            public byte byChanNum;                    //模拟通道个数
            public byte byStartChan;                    //起始通道号,例如DVS-1,DVR - 1
            public byte byAudioChanNum;                //语音通道数
            public byte byIPChanNum;                    //最大数字通道个数
            public byte[] byRes1 = new byte[24];                    //保留
        }
    
        class NET_DVR_THERMOMETRY_PRESETINFO extends Structure {
            public int dwSize;//结构体大小
            public short wPresetNo;//0-保留
            public byte[] byRes = new byte[2];
            public NET_DVR_THERMOMETRY_PRESETINFO_PARAM[] struPresetInfo = new NET_DVR_THERMOMETRY_PRESETINFO_PARAM[40];
        }
    
        class NET_DVR_THERMOMETRY_PRESETINFO_PARAM extends Structure {
            public byte byEnabled;  //是否使能:0- 否,1- 是
            public byte byRuleID;//规则ID 0-表示无效,从1开始 (list内部判断数据有效性)
            public short wDistance;//距离(m)[0, 10000]
            public float fEmissivity;//发射率(发射率 精确到小数点后两位)[0.01, 1.00](即:物体向外辐射能量的本领)
            public byte byDistanceUnit;//距离单位: 0-米(m),1-英尺(feet),2-厘米(centimeter)
            public byte[] byRes = new byte[2];
            public byte byReflectiveEnabled;//反射温度使能:0- 否,1- 是
            public float fReflectiveTemperature;//反射温度 精确到小数后2位
            public byte[] szRuleName = new byte[NAME_LEN/*32*/];//规则名称
            public byte[] byRes1 = new byte[63];
            public byte byRuleCalibType;//规则标定类型 0-点,1-框,2-线
            public NET_VCA_POINT struPoint;//点测温坐标(当规则标定类型为"点"的时候生效)
            public NET_VCA_POLYGON struRegion;//区域、线(当规则标定类型为"框"或者"线"的时候生效)
        }
    
        class NET_VCA_POINT extends Structure {
            public float fX;                                // X轴坐标, 0.001~1
            public float fY;                                //Y轴坐标, 0.001~1
        }
    
        class NET_VCA_POLYGON extends Structure {
            public int dwPointNum;                                  //有效点 大于等于3,若是3点在一条线上认为是无效区域,线交叉认为是无效区域
            public NET_VCA_POINT[] struPos = new NET_VCA_POINT[10]; //多边形边界点,最多十个
        }
    
        class NET_DVR_THERMOMETRY_COND extends Structure {
            public int dwSize;//结构体大小
            public int dwChannel;
            public short wPresetNo;//0-保留
            public byte[] byRes = new byte[62];
        }
    
        class NET_DVR_STD_CONFIG extends Structure {
            public Pointer lpCondBuffer;        //[in]条件参数(结构体格式),例如通道号等.可以为NULL
            public int dwCondSize;            //[in] lpCondBuffer指向的内存大小
            public Pointer lpInBuffer;            //[in]输入参数(结构体格式),设置时不为NULL,获取时为NULL
            public int dwInSize;            //[in] lpInBuffer指向的内存大小
            public Pointer lpOutBuffer;        //[out]输出参数(结构体格式),获取时不为NULL,设置时为NULL
            public int dwOutSize;            //[in] lpOutBuffer指向的内存大小
            public Pointer lpStatusBuffer;        //[out]返回的状态参数(XML格式),获取成功时不会赋值,如果不需要,可以置NULL
            public int dwStatusSize;        //[in] lpStatusBuffer指向的内存大小
            public Pointer lpXmlBuffer;    //[in/out]byDataType = 1时有效,xml格式数据
            public int dwXmlSize;      //[in/out]lpXmlBuffer指向的内存大小,获取时同时作为输入和输出参数,获取成功后会修改会实际长度,设置时表示实际长度,而不是整个内存大小
            public byte byDataType;     //[in]输入/输出参数类型,0-使用结构体类型lpInBuffer/lpOutBuffer有效,1-使用XML类型lpXmlBuffer有效
            public byte[] byRes = new byte[23];
        }
    
        class BYTE_ARRAY extends Structure {
            public byte[] byValue;
    
            public BYTE_ARRAY(int iLen) {
                byValue = new byte[iLen];
            }
    
            @Override
            protected List<String> getFieldOrder() {
                return Arrays.asList("byValue");
            }
        }
    
        //设备抓图附加全屏测温数据结构体
        class NET_DVR_JPEGPICTURE_WITH_APPENDDATA extends Structure {
            public int dwSize;
            public int dwChannel;//通道号
            public int dwJpegPicLen;//Jpeg图片长度
            public Pointer pJpegPicBuff;//Jpeg图片指针
            public int dwJpegPicWidth;  // 图像宽度
            public int dwJpegPicHeight;  //图像高度
            public int dwP2PDataLen;//全屏测温数据长度
            public Pointer pP2PDataBuff; //全屏测温数据指针
            public byte byIsFreezedata;//是否数据冻结 0-否 1-是
            public byte[] byRes = new byte[255];
        }
    }
    

    下面是运行结果:


    image.png

    相关文章

      网友评论

          本文标题:Java调用海康sdk操作热成像设备获取对应点温度

          本文链接:https://www.haomeiwen.com/subject/dztshltx.html