一、功能说明

  • 建立卡扣抓拍车辆信息,之后结合业务数据形成智能预警、非法报警等功能。

  • 本示例仅做到将抓拍车辆相关信息存入数据库,抓拍图片存放服务器磁盘指定目录,如需求不符合可以绕开,解约您宝贵时间。

二、项目环境

Spring Boot、JDK 1.8、IntelliJ IDEA 2020、SDK V6.1、MySql 5.7、康威视抓拍摄像头(iDS-2CD9545-GSZ/GSJK

接触海康摄像头二开少的朋友可以先看看,如何接入海康SDK详细说明:海康威视SDK二次开发JAVA(SpringBoot)

三、 详细步骤

摄像头硬件系统配置和程序编程二次开发记录整个步骤。

3.2 摄像头配置

  1. 浏览器输入摄像头ip,登录账户密码后面,进入页面配置并保存。
    在这里插入图片描述

3.3 二开代码

  1. 如图创建Spring boot项目,整体项目目录结构如图:
    在这里插入图片描述
    数据库创建库>>导入sql>>修改配置文件即可启动项目。抓拍摄像头信息根据实际情况填入sys_camera表。

源码地址:代码地址https://download.csdn.net/download/qq_35719898/92690222?spm=1001.2014.3001.5503

  1. HCNetSDK.java,修改为自定义位置。
    在这里插入图片描述

  2. HikVisionService.java摄像头创建连接、布防、建立监听、回调获取抓拍数据,示例关键核心代码,注:代码注释标注很清楚不过多说明

package com.xzl.common.hkSdk.HkService;

import com.xzl.common.hkSdk.ClientDemo.HCNetSDK;
import com.xzl.dao.SafeMonitorSiteDAO;
import com.xzl.entity.SafeMonitorSite;
import com.xzl.entity.SysCamera;
import com.xzl.vo.*;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.xzl.common.hkSdk.ClientDemo.HCNetSDK.COMM_ITS_PLATE_RESULT;

public class HikVisionService {

    private static Logger logger = LoggerFactory.getLogger(HikVisionService.class);

    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    static short m_sPort = 8000;//端口号,这是默认的
    public NativeLong lUserID;//用户句柄
    public NativeLong lAlarmHandle;//报警布防句柄
    public int lListenHandle;//报警监听句柄
    public boolean callback; // 回调状态
    public void initMemberFlowUpload(SysCamera camera, Map<String, SysCamera> mapCamera, SafeMonitorSiteDAO safeMonitorSiteDAO, String fileSavePath) throws InterruptedException {
        String m_sDeviceIP = camera.getIp();
        String m_sUsername = camera.getAccount();
        String m_sPassword = camera.getPassword();
        // 初始化
        boolean flag = hCNetSDK.NET_DVR_Init();
        if (flag) {
            System.out.println("初始化成功");
        } else {
            System.out.println("初始化失败");
        }
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        //设备信息, 输出参数
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
        // 注册设备-登录参数,包括设备地址、登录用户、密码等
        m_strLoginInfo.sDeviceAddress = new byte[hCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        m_strLoginInfo.sUserName = new byte[hCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        m_strLoginInfo.sPassword = new byte[hCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = m_sPort;
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
        m_strLoginInfo.write();

        //设备信息, 输出参数
        lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (lUserID.intValue() < 0) {
            System.out.println("hCNetSDK.NET_DVR_Login_V30()" + "\n" + hCNetSDK.NET_DVR_GetErrorMsg(null));
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }
        callback = hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(new HikVisionService().new FMSGCallBack(safeMonitorSiteDAO, fileSavePath, mapCamera), null);

        //设置报警回调函数
        if (!callback) {
            System.out.println("设置回调函数失败" + hCNetSDK.NET_DVR_GetLastError());
            return;
        } else {
            System.out.println("设置回调函数成功");
        }
        //启用布防
        HCNetSDK.NET_DVR_SETUPALARM_PARAM lpSetupParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
        lpSetupParam.dwSize = 0;
        lpSetupParam.byLevel = 0;//布防优先级:0- 一等级(高),1- 二等级(中)
        lpSetupParam.byAlarmInfoType = 1;//上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
        lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, lpSetupParam);
        if (lAlarmHandle.intValue() < 0) {
            System.out.println("NET_DVR_SetupAlarmChan_V41 error, %d\n" + hCNetSDK.NET_DVR_GetLastError());
            hCNetSDK.NET_DVR_Logout(lUserID);
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }
        System.out.println("布防成功,开始监测车辆");

        //启动监听----------------------------------------------
        int iListenPort = 9999;
        String m_sListenIP = "127.0.0.1";

        lListenHandle = hCNetSDK.NET_DVR_StartListen_V30(m_sListenIP, (short) iListenPort, new HikVisionService().new FMSGCallBack(safeMonitorSiteDAO, fileSavePath, mapCamera), null);
        if (lListenHandle < 0) {
            System.out.println("启动监听失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
        } else {
            System.out.println("启动监听成功");
        }
    }

    public class FMSGCallBack implements HCNetSDK.FMSGCallBack {
        /**
         * 文件存放地址
         */
        private String fileSavePath;
        /**
         * 抓拍数据存储位置
         */
        private SafeMonitorSiteDAO safeMonitorSiteDAO;

        /**
         * 相机
         */
        public Map<String, SysCamera> mapCamera;

        public FMSGCallBack(SafeMonitorSiteDAO safeMonitorSiteDAO, String fileSavePath, Map<String, SysCamera> mapCamera) {
            this.fileSavePath = fileSavePath;
            this.safeMonitorSiteDAO = safeMonitorSiteDAO;
            this.mapCamera = mapCamera;
        }

        @Override
        public void invoke(NativeLong lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
            System.out.println("〈--进入回调,开始识别车牌--〉");
            try {
                String sAlarmType;
                DateTimeFormatter sf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                DateTimeFormatter sfDay = DateTimeFormatter.ofPattern("yyyyMMdd");
                LocalDateTime now = LocalDateTime.now();
                switch (lCommand.intValue()) {
                    case COMM_ITS_PLATE_RESULT:    //交通抓拍的终端图片上传
                        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();
                        // 全车牌号
                        String carNumber = new String(strItsPlateResult.struPlateInfo.sLicense, "GBK");
                        // 车牌号
                        String plateNumber = carNumber.substring(1).trim();
                        // //省份
                        String byCountry = carNumber.substring(1, 2).trim();
                        // 车牌颜色
                        String byColor = carNumber.substring(0, 1).trim();
                        // 相机ip
                        String cameraIp = new String(pAlarmer.sDeviceIP).trim();
                        // 车辆类型
                        String carType = CarType.getCarType(strItsPlateResult.byVehicleType + "".trim());
                        // 车道
                        String driveChan = strItsPlateResult.byDriveChan + "".trim();
                        // 速度
                        String wSpeed = String.valueOf(new Random().nextInt(55 - 5) + 5);
                        // 相机对象
                        SysCamera camera = mapCamera.get(cameraIp);
                        if (camera == null) {
                            camera = new SysCamera();
                        }
                        String cameraId = camera.getId() == null ? "获取Id失败" : camera.getId();
                        sAlarmType = driveChan + "车道,抓拍车辆类型:" + carType + ",上传车牌:" + carNumber + ">>" + plateNumber + "相机标识:" + cameraId;
                        logger.info("识别信息:---》" + sAlarmType + " ip:" + new String(pAlarmer.sDeviceIP).trim() + "时间:" + now);
                        // 图片保存
                        String imgName = sf.format(now) + ".jpg";
                        String pathUrl = cameraId + "/" + sfDay.format(now) + "/";
                        // 车牌图片地址
                        String filename = pathUrl + imgName;
                        // 场景图片地址
                        String carFileName = pathUrl + "cj_" + imgName;

                        for (int i = 0; i < strItsPlateResult.dwPicNum; i++) {
                            if (strItsPlateResult.struPicInfo[i].dwDataLen > 0) {
                                FileOutputStream fout;
                                // 车牌照片
                                if (strItsPlateResult.struPicInfo[i].byType == 0) {
                                    String url = fileSavePath + filename;
                                    File file = new File(url);
                                    if (!file.getParentFile().exists()) {
                                        file.getParentFile().mkdirs();
                                    }
                                    fout = new FileOutputStream(url);
                                    logger.info("文件路径" + url);
                                    //将字节写入文件
                                    long offset = 0;
                                    ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(offset, strItsPlateResult.struPicInfo[i].dwDataLen);
                                    byte[] bytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];
                                    buffers.rewind();
                                    buffers.get(bytes);
                                    fout.write(bytes);
                                    fout.close();
                                }
                                // 场景照片
                                if (strItsPlateResult.struPicInfo[i].byType == 1) {
                                    String url = fileSavePath + carFileName;
                                    File file = new File(url);
                                    if (!file.getParentFile().exists()) {
                                        file.getParentFile().mkdirs();
                                    }
                                    fout = new FileOutputStream(url);
                                    logger.info("文件路径" + url);
                                    //将字节写入文件
                                    long offset = 0;
                                    ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(offset, strItsPlateResult.struPicInfo[i].dwDataLen);
                                    byte[] bytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];
                                    buffers.rewind();
                                    buffers.get(bytes);
                                    fout.write(bytes);
                                    fout.close();
                                }
                            }
                        }
                        // 创建对接保存数据库
                        SafeMonitorSite safeMonitorSite = new SafeMonitorSite();
                        safeMonitorSite.setPictureTime(now);
                        safeMonitorSite.setPointName(camera.getPointName());
                        safeMonitorSite.setCarNumber(plateNumber);
                        safeMonitorSite.setCarPicture(filename);
                        safeMonitorSite.setLicensePicture(carFileName);
                        safeMonitorSite.setCarType(carType);
                        safeMonitorSite.setInOut(0);
                        safeMonitorSite.setOperator("自动");
                        safeMonitorSite.setOperatorIp(cameraIp);
                        safeMonitorSite.setGmtCreate(now);
                        safeMonitorSite.setGmtModified(now);
                        safeMonitorSiteDAO.insert(safeMonitorSite);
                        break;
                    default:
                        System.out.println("回调获取数据类型错误:" + lCommand.intValue());
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.info(e.toString() + "故障");
            }
        }
    }
}

4.运行后,开启抓拍调用接口:http://127.0.0.1:8080/dotask。注意:开启后必须有车辆经过才有数据推送,手动布防抓拍车辆,不会推送数据。

5.结果展示
在这里插入图片描述
在这里插入图片描述

结束赶紧试一下,过程中有问题可以留言一起交流

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐