Java Hikvision SDK License Plate Recognition Secondary Development

Project scenario:

License plate recognition through Hikvision cameras.

Pay attention to avoid pits:

(1) Put the HCNetSDK.dll, HCCore.dll, HCNetSDKCom folder, libssl-1_1-x64.dll.dll, libcrypto-1_1-x64.dll.dll, hlog.dll, hpr.dll in the [Library File] of the official document , zlib1.dll, log4cxx.properties and other files are copied to the same directory as java.exe ( xxx/jdk/bin or xxx/jdk/jre/bin ).

(2) Copy HCNetSDK.java from the official DEMO to the project.

(3) Load HCNetSDK.dll (add the following content in HCNetSDK.java)

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

 (4) Inheriting Structure may report an error, you need to add HIKSDKStructure to rewrite, and then change all inherited Structures in HCNetSDK.java to inherit 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;
    }
}


overall process

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

   


SDK initialization:

Tips: lUserID = the number of handles returned after connecting the camera (0 for success).

/**
     * 初始化连接摄像头
     */
    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();
        }

    }

Get device capabilities:

Tip: Get Device Capabilities Through Connection Handle

Ability type Ability value describe
IPC_FRONT_PARAMETER_V20 0x009 Device front-end parameters
DEVICE_ABILITY_INFO 0x011 Capabilities of intelligent traffic cameras and ITS intelligent terminal equipment
SNAPCAMERA_ABILITY 0x300 Intelligent traffic camera capture capability
ITC_TRIGGER_MODE_ABILITY 0x301 Trigger mode capability for smart traffic cameras (V3.1 and later)
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());
    }


Callback event:

hint::

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;
        }
    }


Start identifying:

Tip: Recognize license plates.

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("设置回调函数成功");
        }
    }


Guess you like

Origin blog.csdn.net/qq_33415990/article/details/129183658