Java海康SDK车牌识别 二次开发

项目场景:

通过海康摄像头进行车牌识别。

注意避坑:

(1)将官方文档的【库文件】里的HCNetSDK.dll、HCCore.dllHCNetSDKCom文件夹、libssl-1_1-x64.dll.dll、libcrypto-1_1-x64.dll.dll、hlog.dll、hpr.dll、zlib1.dll、log4cxx.properties等文件均拷贝到java.exe同级目录下(xxx/jdk/bin或者xxx/jdk/jre/bin)。

(2)把官方DEMO中的HCNetSDK.java拷贝至项目当中。

(3)加载HCNetSDK.dll(在HCNetSDK.java添加以下内容)

HCNetSDK INSTANCE = Native.load( "HCNetSDK", HCNetSDK.class);

 (4)继承Structure可能会报错,需要添加HIKSDKStructure 重写,然后将HCNetSDK.java中所有继承Structure改成继承HIKSDKStructure即可。

package com.support.sdk.hikvision;

import com.sun.jna.Structure;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

public class HIKSDKStructure extends Structure {

    @Override
    protected List<String> getFieldOrder(){
        List<String> fieldOrderList = new ArrayList<String>();
        for (Class<?> cls = getClass();
             !cls.equals(HIKSDKStructure.class);
             cls = cls.getSuperclass()) {
            Field[] fields = cls.getDeclaredFields();
            int modifiers;
            for (Field field : fields) {
                modifiers = field.getModifiers();
                if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
                    continue;
                }
                fieldOrderList.add(field.getName());
            }
        }
        return fieldOrderList;
    }
}


总体流程

  1. 初始化SDK
  2. 设置报警回调函数
  3. 用户登录
  4. 获取设备能力集(是否具备车牌识别能力)
  5. 配置报警条件(可选)
  6. 报警布防
  7. 报警回调函数里面接收和处理数据(可选)
  8. 报警撤防
  9. 登出
  10. 释放SDK资源     

   


SDK初始化:

提示:lUserID=连接摄像头后返回的句柄数(0成功)。

/**
     * 初始化连接摄像头
     */
    private void initConn(String deviceIp, Short devicePort, String userName, String pwd) {
        // SDK未初始化
        boolean initSuc = HCNetSDK.INSTANCE.NET_DVR_Init();
        if (!initSuc) {
            log.error("SDK初始化失败");
            return;
        }

        //设置连接时间与重连时间
        HCNetSDK.INSTANCE.NET_DVR_SetConnectTime(2000, 1);
        HCNetSDK.INSTANCE.NET_DVR_SetReconnect(100000, true);

        // 设备登录信息
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();

        // 设备信息
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();

        // 设置ip、port、userName、pwd
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(deviceIp.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, deviceIp.length());
        m_strLoginInfo.wPort = devicePort;
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(userName.getBytes(), 0, m_strLoginInfo.sUserName, 0, userName.length());
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(pwd.getBytes(), 0, m_strLoginInfo.sPassword, 0, pwd.length());


        // 是否异步登录:false- 否,true- 是
        m_strLoginInfo.bUseAsynLogin = false;
        m_strLoginInfo.write();
        lUserID = HCNetSDK.INSTANCE.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);

        if (lUserID == -1) {
            System.out.println("登录失败,错误码为" + HCNetSDK.INSTANCE.NET_DVR_GetLastError());
            HCNetSDK.INSTANCE.NET_DVR_Cleanup();
            return;
        } else {
            System.out.println("登录成功!");
            // read()后,结构体中才有对应的数据
            m_strDeviceInfo.read();
        }

    }

获取设备能力:

提示:通过连接句柄获取设备能力

能力类型 能力值 描述
IPC_FRONT_PARAMETER_V20 0x009 设备前端参数
DEVICE_ABILITY_INFO 0x011 智能交通摄像机和ITS智能终端设备能力
SNAPCAMERA_ABILITY 0x300 智能交通摄像机抓拍能力
ITC_TRIGGER_MODE_ABILITY 0x301 智能交通摄像机(V3.1及以后版本)的触发模式能力
private boolean getCameraAbility() {
        HCNetSDK.NET_DVR_STD_ABILITY ability = new HCNetSDK.NET_DVR_STD_ABILITY();
        ability.dwOutSize = ability.size();
        ability.write();
        return HCNetSDK.INSTANCE.NET_DVR_GetDeviceAbility(lUserID, 0x011, null, 0, ability.getPointer(), ability.size());
    }


回调事件:

提示::

public boolean CarNumberCallBack(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        log.info("开始回调事件,开始识别车牌=====================");
        try {
            // 接收对车辆信息对象
            CarNumberCapturedArgs carInfo = new CarNumberCapturedArgs();
            switch (lCommand) {
                //COMM_ITS_PLATE_RESULT 交通抓拍
                case 0x3050:
                    HCNetSDK.NET_ITS_PLATE_RESULT strItsPlateResult = new HCNetSDK.NET_ITS_PLATE_RESULT();
                    strItsPlateResult.write();
                    Pointer pItsPlateInfo = strItsPlateResult.getPointer();
                    pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, strItsPlateResult.size()), 0, strItsPlateResult.size());
                    strItsPlateResult.read();
                    try {
                        // 获取车牌号
                        String carNumber = new String(strItsPlateResult.struPlateInfo.sLicense, "GBK");
                        carInfo.setCarNumber(carNumber);
                    } catch (UnsupportedEncodingException e1) {
                        e1.printStackTrace();
                    }

                    try {
                        for (int i = 0; i < strItsPlateResult.dwPicNum; i++) {
                            if (strItsPlateResult.struPicInfo[i].dwDataLen > 0) {
                                //1.车辆场景图片(大图)  0.车牌图片(小图)
                                if (strItsPlateResult.struPicInfo[i].byType == 1) {
                                    //将字节写入
                                    ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(0L, strItsPlateResult.struPicInfo[i].dwDataLen);
                                    byte[] imageBigBytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];
                                    buffers.rewind();
                                    buffers.get(imageBigBytes);
                                    carInfo.setFullImage(imageBigBytes);
                                } else if (strItsPlateResult.struPicInfo[i].byType == 0) {
                                    //将字节写入
                                    ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(0L, strItsPlateResult.struPicInfo[i].dwDataLen);
                                    byte[] imageSmallBytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];
                                    buffers.rewind();
                                    buffers.get(imageSmallBytes);
                                    carInfo.setCarNumberImage(imageSmallBytes);
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    break;
                default:
                    break;
            }
            log.info("识别信息======================" + JSONObject.toJSON(carInfo));
            // TODO 将识别后的信息传到业务模块
            
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


开始识别:

提示:识别车牌。

public void carNumberRecognize() {
        // 判断摄像头是否有车牌识别能力
        if (!getCameraAbility()) {
            log.error(String.format("%s摄像头无车牌识别功能,ip=%s,port=%d", name, ip, port));
            return;
        }

        //启用布防
        HCNetSDK.NET_DVR_SETUPALARM_PARAM lpSetupParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
        lpSetupParam.dwSize = 0;

        //布防优先级:0 = 一等级(高),1 = 二等级(中)
        lpSetupParam.byLevel = 1;

        //上传报警信息类型: 0 = 老报警信息(NET_DVR_PLATE_RESULT), 1 = 新报警信息(NET_ITS_PLATE_RESULT)
        lpSetupParam.byAlarmInfoType = 1;
        int lAlarmHandle = HCNetSDK.INSTANCE.NET_DVR_SetupAlarmChan_V41(lUserID, lpSetupParam);
        if (lAlarmHandle < 0) {
            log.error(String.format("%s启动车牌识别失败,错误代码= %d", name, HCNetSDK.INSTANCE.NET_DVR_GetLastError()));
            HCNetSDK.INSTANCE.NET_DVR_Logout(lUserID);
            HCNetSDK.INSTANCE.NET_DVR_Cleanup();
            return;
        }

        //  设置报警回调函数
        if (!HCNetSDK.INSTANCE.NET_DVR_SetDVRMessageCallBack_V30(this::CarNumberCallBack, null)) {
            log.error(String.format("%s设置回调函数失败,错误代码= %d", name, HCNetSDK.INSTANCE.NET_DVR_GetLastError()));
            log.error("设置回调函数失败" + HCNetSDK.INSTANCE.NET_DVR_GetLastError());
            return;
        } else {
            log.info("设置回调函数成功");
        }
    }


猜你喜欢

转载自blog.csdn.net/qq_33415990/article/details/129183658
今日推荐