zoukankan      html  css  js  c++  java
  • Java调用海康SDK读取图像

    前言

    视频识别的一个项目,前期采用Java调用OpenCV读取的方案,然后发送到Redis服务器,由于OpenCV采图像不稳定,需要研究使用海康SDK读取图像。由于本人海康SDK的demo已成功运行,这里直接删除了demo里不需要的东西,demo正常运行也会附到本文。
    海康windows64SDK下载
    opencv-4-4-0下载
    代码示例下载

    1、加载动态链接库dll

    下载海康SDK,并放到指定文件夹

    HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("D:\Java\HCNetSDK\库文件\HCNetSDK.dll", HCNetSDK.class);
    
    PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("D:\Java\HCNetSDK\库文件\PlayCtrl.dll", PlayCtrl.class);
    

    这里采用了直接加载dll的方式,没有用eclipse加载lib文件的方式,HCNetSDK用于登录、预览,PlayCtrl用于播放,OpenCV 4.4.0

    2、调用逻辑

    先调用NET_DVR_Init方法进行初始化,调用NET_DVR_Login_V30进行登录,调用NET_DVR_RealPlay_V30进行预览

    重点来了

    lPreviewHandle = hCNetSDK.NET_DVR_RealPlay_V30(lUserID, m_strClientInfo, fRealDataCallBack, null, true);
    

    这里需要fRealDataCallBack预览回调,是一个参数,需要自定义一个类去实现一个接口,

    case HCNetSDK.NET_DVR_SYSHEAD是预览时第一次会进入系统头这个逻辑,相当于配置一下,这里是配置了PlayM4_SetDecCallBackSDK解码回调,这里需要一个fDecCallBackSDK解码回调函数,在下面附上

    case HCNetSDK.NET_DVR_STREAMDATA:是上面配置完,下一次就会进入这个case语句,这个逻辑是放入码流数据

        class FRealDataCallBack implements HCNetSDK.FRealDataCallBack_V30 {
            public void invoke(NativeLong lRealHandle, int dwDataType, ByteByReference pBuffer, int dwBufSize, Pointer pUser) {
                switch (dwDataType) {
                    case HCNetSDK.NET_DVR_SYSHEAD: //系统头
                        System.out.println(logHead + "FRealDataCallBack 系统头");
                        if (!playControl.PlayM4_GetPort(m_lPort)) //获取播放库未使用的通道号
                        {
                            break;
                        }
                        if (dwBufSize > 0) {
                            if (!playControl.PlayM4_SetDecCallBack(m_lPort.getValue(), fDecCallBack))  //设置解码回调
                            {
                                break;
                            }
                            // 设置解码回调函数 解码且显示
                            // if (!playControl.PlayM4_SetDecCallBackEx(m_lPort.getValue(), fDecCallBack, null, null)) {
                            //     break;
                            // }
                            if (!playControl.PlayM4_SetStreamOpenMode(m_lPort.getValue(), PlayCtrl.STREAME_REALTIME))  //设置实时流播放模式
                            {
                                break;
                            }
    
                            if (!playControl.PlayM4_OpenStream(m_lPort.getValue(), pBuffer, dwBufSize, 1024 * 1024)) //打开流接口
                            {
                                break;
                            }
                            if (!playControl.PlayM4_Play(m_lPort.getValue(), null)) //播放开始
                            {
                                break;
                            }
                        }
                    case HCNetSDK.NET_DVR_STREAMDATA:   //码流数据
                        if (!playControl.PlayM4_InputData(m_lPort.getValue(), pBuffer, dwBufSize)) {
                            break;
                        }
                }
            }
        }
    

    fDecCallBackSDK解码回调函数如下,解码回调函数里面的数据,是sdk软解码以后的数据,可以直接拿来处理,不过里面的代码需要在40ms里处理完毕,不然会产生很大的延迟

        class FDecCallBack implements PlayCtrl.DecCallBack {
            @Override
            public void invoke(NativeLong nPort, ByteByReference pBuffer, NativeLong nSize, PlayCtrl.FRAME_INFO frameInfo, NativeLong nReserved1, NativeLong nReserved2) {
                if (++count % 6 == 0) {
                    try {
                        handle(pBuffer, nSize.intValue(), frameInfo);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
    
            //这样在回调函数DecCallBack 中可以得到视音频数据,其中视频数据是YV12格式的,音频数据是PCM格式的。
            public void handle(ByteByReference pBuffer, int dwBufSize, PlayCtrl.FRAME_INFO frameInfo) {
                src = null;
                dst = null;
                bufferedImage = null;
                boolean isLog = new Date().getSeconds() % 10 == 0;
                String printStr = null;
                if (isLog) {
                    stopWatch.reset();
                    stopWatch.start();
                }
    
                int width = frameInfo.nWidth.intValue();
                int height = frameInfo.nHeight.intValue();
                byte[] byteArray = pBuffer.getPointer().getByteArray(0, dwBufSize);
    
                src = new Mat(height + height / 2, width, CvType.CV_8UC1);
                src.put(0, 0, byteArray);
                if (isLog) {
                    stopWatch.split();
                    printStr = "";
                    printStr += logHead + "put " + stopWatch.getSplitTime() + "
    ";
                }
    
                dst = new Mat(height, width, CvType.CV_8UC3);
                Imgproc.cvtColor(src, dst, Imgproc.COLOR_YUV2BGR_YV12);
                if (isLog) {
                    stopWatch.split();
                    printStr += logHead + "cvtColor " + stopWatch.getSplitTime() + "
    ";
                }
    
                bufferedImage = Mat2BufImg.Mat2BufImg(dst);
                if (isLog) {
                    stopWatch.split();
                    printStr += logHead + "Mat2BufImg " + stopWatch.getSplitTime() + "
    ";
                }
    
                String imgHex = Mat2BufImg.bufImgToBase64(bufferedImage, "jpg");
                if (isLog) {
                    stopWatch.split();
                    printStr += logHead + "bufImgToBase64 " + stopWatch.getSplitTime() + "
    ";
                }
    
                Jedis jedis = JedisUtil.getJedis();
                jedis.set(ip, imgHex);
                JedisUtil.close(jedis);
                if (isLog) {
                    stopWatch.split();
                    printStr += logHead + "set " + stopWatch.getSplitTime() + "
    ";
                    System.out.println(printStr);
                }
            }
        }
    

    3、结尾

    大体流程就是这样子,要不我画一张流程图哇,哈哈

  • 相关阅读:
    第11组 Beta版本演示
    第11组 Beta冲刺(5/5)
    第11组 Beta冲刺(4/5)
    第11组 Beta冲刺(3/5)
    第11组 Beta冲刺(2/5)
    第11组 Beta冲刺(1/5)
    第11组 Alpha冲刺(2/6)
    第11组 Alpha冲刺(1/6)
    第11组 团队Git现场编程实战
    团队项目-需求分析报告
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/14854814.html
Copyright © 2011-2022 走看看