【目标识别】--【截图程序】海康摄像头sdk二次开发自动多摄像头截图程序
目录
背景:
1、问题
2、截图程序自动化和多通道实现
3、摄像头参数灵活化
至此已经全部结束,运行程序可以看到
背景:
目标识别需要对每一帧图像进行检测,因此我们需要将摄像头获取的视频流转换成单帧图像,海康威视官网提供的原本的sdk包实现了点击抓图按钮就截一张图,并且不支持多摄像头截图。海康威视的sdk下载链接为SDK下载
Java版本实现单通道结果如图,在红框内输入摄像头的数据--单机注册--预览就可以看到右边摄像头实时画面了。
1、问题
对于我们的目标检测需求来说,需要解决以下几个问题:
- 截图程序自动化,例如每一秒截一张图,而不需要手动点击抓图
- 截图程序能够实现多通道截图,而不是只能使用单通道
- 摄像头配置灵活化,应该利用数据库存储每个摄像头参数,然后程序读取数据库的摄像头数据。
2、截图程序自动化和多通道实现
解决自动化问题和多通道问题我的主要思路为通过多线程(Threads)来完成,利用线程的sleep(XXX)方法,根据设定的xxx来实现自动截图。下面解释一下我的代码
(1)实现runnable接口,重写run方法
public class MultiThreaded implements Runnable {private MonitorCameraInfo cameraInfo;//创建构造方法,在new的时候外界传递摄像头参数对象cameraInfo。public MultiThreaded(MonitorCameraInfo cameraInfo){this.cameraInfo=cameraInfo;}//默认的构造参数public MultiThreaded() {}//重写接口的run方法;这部分后期摄像头多的情况下需要改成线程池的方法@Overridepublic void run() {// TODO Auto-generated method stubMultiThreaded mt = new MultiThreaded();//while目的是实现自动截图,配合sleep函数while(true){//调用摄像头注册验证功能模块mt.getDVRConfig(cameraInfo);try {//主要作用是截图并存储mt.getDVRPic(cameraInfo);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
(2)注册和验证摄像头 以及 抓图功能
/*** 注册摄像头以及验证* @param cameraInfo*/public void getDVRConfig(MonitorCameraInfo cameraInfo) { HCNetSDK sdk = HCNetSDK.INSTANCE; //判断摄像头是否开启 if (!sdk.NET_DVR_Init()) { System.out.println("SDK初始化失败"); return; } NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息 //登录信息 NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(), cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo); cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo if (cameraInfo.getUserId().intValue() < 0) { System.out.println("设备注册失败"); return; } //DVR工作状态 NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30(); if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) { // 返回Boolean值,判断是否获取设备能力 System.out.println("返回设备状态失败"); } IntByReference ibrBytesReturned = new IntByReference(0);// 获取IP接入配置参数 NET_DVR_IPPARACFG ipcfg = new NET_DVR_IPPARACFG();//IP接入配置结构 ipcfg.write(); Pointer lpIpParaConfig = ipcfg.getPointer(); //获取相关参数配置 sdk.NET_DVR_GetDVRConfig(cameraInfo.getUserId(), HCNetSDK.NET_DVR_GET_IPPARACFG, new NativeLong(0), lpIpParaConfig, ipcfg.size(), ibrBytesReturned); ipcfg.read(); System.out.print("IP地址:" + cameraInfo.getCameraIp()); System.out.println("|设备状态:" + devwork.dwDeviceStatic);// 0正常,1CPU占用率过高,2硬件错误,3未知 //System.out.println("ChanNum"+devinfo.byChanNum); // 显示模拟通道 for (int i = 0; i < devinfo.byChanNum; i++) { System.out.print("Camera" + i + 1);// 模拟通道号名称 System.out.print("|是否录像:" + devwork.struChanStatic[i].byRecordStatic);// 0不录像,不录像 System.out.print("|信号状态:" + devwork.struChanStatic[i].bySignalStatic);// 0正常,1信号丢失 System.out.println("|硬件状态:" + devwork.struChanStatic[i].byHardwareStatic);// 0正常,1异常 } //注销用户 sdk.NET_DVR_Logout(cameraInfo.getUserId());//释放SDK资源 sdk.NET_DVR_Cleanup(); } /*** 抓拍图片 * @param cameraInfo* @throws IOException*/public void getDVRPic(MonitorCameraInfo cameraInfo) throws IOException { //设置通道号,其中1正常,-1不正常 NativeLong chanLong = new NativeLong(1); cameraInfo.setChannel(chanLong); //System.out.println("Channel:"+chanLong); long startTime = System.currentTimeMillis(); HCNetSDK sdk = HCNetSDK.INSTANCE; if (!sdk.NET_DVR_Init()) { System.out.println("SDK初始化失败"); return; } NET_DVR_DEVICEINFO_V30 devinfo = new NET_DVR_DEVICEINFO_V30();// 设备信息 //注册设备 NativeLong id = sdk.NET_DVR_Login_V30(cameraInfo.getCameraIp(), (short) cameraInfo.getCameraPort(), cameraInfo.getUserName(), cameraInfo.getUserPwd(), devinfo); cameraInfo.setUserId(id);// 返回一个用户编号,同时将设备信息写入devinfo if (cameraInfo.getUserId().intValue() < 0) { System.out.println("设备注册失败"+sdk.NET_DVR_GetLastError()); return; } else { System.out.println("id:" + cameraInfo.getUserId().intValue()); } NET_DVR_WORKSTATE_V30 devwork = new NET_DVR_WORKSTATE_V30(); if (!sdk.NET_DVR_GetDVRWorkState_V30(cameraInfo.getUserId(), devwork)) { // 返回Boolean值,判断是否获取设备能力 System.out.println("返回设备状态失败"); } //System.out.println("设备注册耗时:[" + (System.currentTimeMillis() - startTime) + "]"); startTime = System.currentTimeMillis(); //图片质量 NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA(); // 设置图片的分辨率 jpeg.wPicSize = 2; // 设置图片质量 jpeg.wPicQuality = 2; IntByReference a = new IntByReference(); //设置图片大小 ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024); // 创建文件目录和文件 SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); Date date = new Date(); //按照每天设置一个目录 String fileName = cameraInfo.getPath() +sd.format(date) ; File files = new File(fileName); if(!files.exists()){ files.mkdirs(); } //按照日期文件夹放入图片 String fileNameString = fileName+"/"+ cameraInfo.getId()+sdf.format(date)+".jpg"; System.out.println(fileNameString); File file = new File(fileNameString); // 抓图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中 //需要加入通道 boolean is = sdk.NET_DVR_CaptureJPEGPicture_NEW(cameraInfo.getUserId(), cameraInfo.getChannel(), jpeg, jpegBuffer, 1024 * 1024, a); //System.out.println("Channel:"+cameraInfo.getChannel()); System.out.println("抓图到内存耗时:[" + (System.currentTimeMillis() - startTime) + "ms]"); // 抓图到文件 //boolean is = sdk.NET_DVR_CaptureJPEGPicture(cameraInfo.UserId,cameraInfo.Channel,jpeg, fileNameString); if (is) { System.out.println("抓取成功,返回长度:" + a.getValue()); } else { System.out.println("抓取失败:"+sdk.NET_DVR_GetLastError()); } //startTime = System.currentTimeMillis(); // 存储本地,写入内容 BufferedOutputStream outputStream = null; try { outputStream = new BufferedOutputStream(new FileOutputStream(file)); outputStream.write(jpegBuffer.array(), 0, a.getValue()); outputStream.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } System.out.println("存储本地耗时:[" + (System.currentTimeMillis() - startTime) + "ms]"); sdk.NET_DVR_Logout(cameraInfo.getUserId()); sdk.NET_DVR_Cleanup(); }
}
(3)多线程通道开启,首先查询数据库获取摄像头总个数,然后根据摄像头个数创建对应的线程数,第二 遍历摄像头集合,创建对应的MultiThread对象,将摄像头作为构造参数赋值;第三开启线程,并配合sleep方法。
3、摄像头参数灵活化
(1)创建数据库,将数据存储到数据库中
(2)Java使用Mybaties作为数据库连接
具体配置等信息可以参考我的博客SSM相关配置;下面大体写一下实现过程
- 创建pojo对象(get set方法篇幅所限省略)
- 数据库连接数据 db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/object_detect?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
- 创建SqlMapConfig.xml文件 功能主要为连接数据库和mapper扫描
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"></properties><typeAliases> <!-- 定义单个pojo类别名type:类的全路劲名称alias:别名-->
<!-- <typeAlias type="cn.chuantao.pojo.User" alias="user"/> --><!-- 使用包扫描的方式批量定义别名 定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写--><package name="pojo"/></typeAliases><!-- 和spring整合后 environments配置将废除--><environments default="development"><environment id="development"><!-- 使用jdbc事务管理--><transactionManager type="JDBC" /><!-- 数据库连接池--><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}" /><property name="url" value="${jdbc.url}" /><property name="username" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></dataSource></environment></environments><mappers><!-- <mapper resource="mapper/FindCamera.xml"/> --><!-- 使用class属性引入接口的全路径名称:使用规则:1. 接口的名称和映射文件名称除扩展名外要完全相同2. 接口和映射文件要放在同一个目录下-->
<!-- <mapper class="cn.chuantao.mapper.UserMapper"/> --><!-- 使用包扫描的方式批量引入Mapper接口 使用规则:1. 接口的名称和映射文件名称除扩展名外要完全相同2. 接口和映射文件要放在同一个目录下--><package name="mapper"/></mappers>
</configuration>
- 创建mapper信息:xml和对应的接口映射
(3)程序:查询数据库得到摄像头配置信息
至此已经全部结束,运行程序可以看到
【目标识别】--【截图程序】海康摄像头sdk二次开发自动多摄像头截图程序相关推荐
- C/C++实战——基于Qt框架和visual studio的海康相机SDK二次开发
最近在进行机器视觉系统的搭建,积累了经验,想和大家讨论.互相学习.相机是图像的来源.为了搭建视觉系统,完成图像分析.机器视觉任务,需要编程控制相机按工作所需的曝光.增益和帧率同步采集和存储图像.工业相 ...
- C#海康摄像机SDK二次开发
海康球机设备网络SDK开发实践记录 获取PTZ参数 开发手册相关内容截图 C# 代码实现 //获取球机位置信息结构体大小 Int32 size = Marshal.SizeOf(typeof(CHCN ...
- 海康相机SDK二次开发的一些报错和解决办法
1.MV_OK 0x00000000 成功,无错误 解析:-2147483648/0x80000000正常状态返回,执行成功 2.MV_E_HANDLE 0x80000000 错误或无效的句 解析:- ...
- 海康相机-SDK二次开发(NVR)-多相机IPCamera连接采集-opencv图像格式转换
主要功能: 海康SDK开发,通过连接NVR,实现连接NVR的2个相机同时采集(多线程),并进行opencv图像格式转换. 关键技术点: 1.回调函数 2.YV12->oepncv图像格式转换 3 ...
- 海康摄像机-新手二次开发
一直对海康摄像机的二次开发感兴趣,之前用Delphi做了些DEMO,能预览和抓图,但太过久远了,海康的SDK与Delphi的开发接口都已经升级了,所以这一回再用Delphi做个通用的Unit.希望对有 ...
- Java 海康录像机(NVRDVR)二次开发-通过时间下载录像和抓图功能
海康录像机还是国内市场比较火的录像机吧!反正我也不知道,我也不敢问啊!╮(︶﹏︶)╭话不多说!赶紧去海康官网选择一个相应sdk开放包下载,这里给老铁们奉上地址:盘他⁽⁽ƪ(•̩̩̩̩_•̩̩̩̩)ʃ⁾ ...
- 海康工业相机LabVIEW二次开发——修改参数、存图
最近使用LabVIEW对海康机器人的工业相机进行二次开发,没有专门介绍LabVIEW的开发手册,本文就简单的写一写单相机取图显示以及存图的开发步骤. 如果各位是直接使用IMAQdx开发的,可以直接下载 ...
- python基于海康设备SDK二次开发(一)
最近做了个小项目,帮助一家企业做LED屏实时显示车间人员考勤信息和显示工作人数,前后选型了好几款最近后选择海康威视的门禁机DS-K1T673M,由于该款设备只是作为人员认证通过用的,没有内置人员考勤组 ...
- 海康视频监控二次开发基于B/S架构
前言 最近做了一个音视频监控模块,是基于海康的视频平台进行的,今天将一些基本的使用分享给大家. 环境准备 由于调用视频监控需要安装一个插件WebComponentsKit.exe,链接: https: ...
最新文章
- 移动音视频SDK工程实践之数据采集和处理
- Win-Get——Windows下的自由软件自动安装程序
- 不支持对系统目录进行即席更新_「目录」让你的文档结构一目了然
- Windows 8桌面的尴尬
- html前端如何缓存页面,Nuxt中如何做页面html缓存
- 数据库数据规范化看不懂_数据库管理系统中的规范化
- 字典(dict)按键(key)和值(value)排序即item()的常用方式
- 案例解析|政府信息化的BI建设应用
- Linux环境下如何编译C++程序
- 常用图像像素格式 NV12、NV2、I420、YV12、YUYV
- 牛顿迭代法的图像推导思路以及代码
- 使用Android Studio 创建第一个Android 应用
- 消除input标签的自动填充 白色背景,及更改字体颜色
- MP4之sample信息
- MySQL感悟_Mysql学习感悟
- openwrt reboot流程
- Matlab如何绘制小提琴图?
- 隐函数存在定理1的几何解释
- 桌面ICON的红图标
- 哀悼日设置网站主题为黑白主题
热门文章
- 汽车控制系统matlab,汽车控制系统建模与仿真(肖仁鑫)-中国大学mooc-题库零氪
- 达内C++视频(全)
- vm14下centos7配置NAT模式
- netty开发tcp服务器最好不要用分隔符DelimiterBasedFrameDecoder这种分包方式
- 外贸企业电子邮箱哪个好?外贸邮箱怎么选择?
- Autodesk Alias AutoStudio 2022.0.1 x64
- windows设置开机启动程序
- 学习笔记----层次分析法
- LabVIEW与Web通讯
- 【Node.js】初识Node.js