海康威视监控相机的SDK与opencv调用(非工业相机)

这篇具有很好参考价值的文章主要介绍了海康威视监控相机的SDK与opencv调用(非工业相机)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.研究内容

本篇主要对海康威视的监控相机的SDK回调进行研究,并于opencv结合,保存图像,以供后续其他处理,开发语言为C++

2.步骤及方法

2.1 海康SDK介绍

海康SDK下载地址
根据自身编译环境,下载对应的SDK,需要注意的是,不要和工业相机SDK相混淆,工业相机好像是MVS是什么玩意儿,现在暂时没研究
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视
SDK包的结构如下,包括需要的头文件和库目录,其中windows下还提供了Demo示例,开发文档是我们时常需要用到的,结构如下:
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视
其中SDK编程指南是需要注意的一个地方,通常需要根据自己的相机型号选择对应的文件,有些相机型号可能不支持,比如我使用的DS-2CD7********,这款相机,就只支持IPC的,查看文档是否支持相机,可以打开文档,在SDK简介中查看:
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视
SDK文件确定后可以开始后续的开发了

2.2 环境搭建

打开visual studio 2022,配置sdk环境,包括前面提到的库文件和头文件,其中用到了opencv,配置opencv的相关头文件和库文件:
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视
配置方式不多说,也可以在VC++目录中添加
添加完成后,编写头文件,蒋需用到的库包含进来,包括opencv的和海康sdk的:
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视
其中有一个PlayM4.h头文件,sdk里面是没有的,需要在示例文件中拷贝过来,opencv如果是编译成一个opencv_world的,直接配置上去就行了

2.3 相机配置

海康相机配置比较容易,初始的IP地址是192.168.1.64,可以根据实际使用情况,修改相机的IP,登录的用户名和密码,sdk调用的时候需要用到这3个信息。

2.4 SDK调用

SDK取流在文档的第4章《函数调用示例》中,直接复制,粘贴,修改好自己相机的IP,用户名和密码就可以正常调用起来了,主要分为以下几个部分:
(1)初始化
初始化,包括设备注册,设置连接时间和重连时间,设置异常回调函数等,其中最重要的是设置登录相机设备的IP地址,用户名和密码。
(2)调用相机
调用相机有多种方式,可以直接使用rtsp取流,也可以直接使用海康sdk提供的回调取流函数,这一部分需要参考sdk开发文档,不只是代码示例,还有sdk提供的其他函数,可参考5《函数说明》,例如,我需要拿到图像后和opencv结合,那么需要拿到图像的数据,就需要用到以下接口了:
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视

3 图像保存

本篇主要解决的问题是,sdk拿到的图像通过opencv保存下来并且可以做其他操作,sdk中提供的参考示例使用了回调函数,这里给出两种保存方法

第一种使用回调函数预览的方式保存图像:

使用预览的方式存图,需要定义一个全局的Mat变量,最终保存图像在回调函数中完成,整个工程实例如下:


#include <opencv2\opencv.hpp>
//#include "hkinterface.h"

#include <HCNetSDK.h>
#include <plaympeg4.h>


#include <PlayM4.h>

using namespace std;
using namespace cv;


Mat g_BGRImage;
LONG g_nPort;

//数据解码回调函数将YV_12格式的视频数据流转码为可供opencv处理的BGR类型的图片数据。
void CALLBACK DecCBFun(long nPort, char* pBuf, long nSize, FRAME_INFO* pFrameInfo, long nUser, long nReserved2)
{
	if (pFrameInfo->nType == T_YV12)
	{
		std::cout << "the frame infomation is T_YV12" << std::endl;
		if (g_BGRImage.empty())
		{
			g_BGRImage.create(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC3);
		}
		Mat YUVImage(pFrameInfo->nHeight + pFrameInfo->nHeight / 2, pFrameInfo->nWidth, CV_8UC1, (unsigned char*)pBuf);

		cvtColor(YUVImage, g_BGRImage, COLOR_YUV2BGR_YV12);
		//保存图像
		static int count = 0;
		count += 1;
		string name = to_string(count) + ".jpg";
		cout << "g_BGRImage: " << g_BGRImage.empty() << "========" << name << endl;
		if (!g_BGRImage.empty()) {
			imwrite("D:\\桌面文件\\save_imgsdk\\" + name, g_BGRImage);
		}
		
		YUVImage.~Mat();
	}
}

//获取播放库通道号
void getPort() {
	if (PlayM4_GetPort(&g_nPort))
	{
		if (PlayM4_SetStreamOpenMode(g_nPort, STREAME_REALTIME))      //设置流模式
		{
			if (PlayM4_OpenStream(g_nPort, NULL, 0, 1440 * 2560))         //打开流
			{
				if (PlayM4_SetDecCallBackExMend(g_nPort, DecCBFun, NULL, 0, NULL))
				{
					if (PlayM4_Play(g_nPort, NULL))
					{
						std::cout << "success to set play mode" << std::endl;
					}
					else
					{
						std::cout << "fail to set play mode" << std::endl;
					}
				}
				else
				{
					std::cout << "fail to set dec callback " << std::endl;
				}
			}
			else
			{
				std::cout << "fail to open stream" << std::endl;
			}
		}
		else
		{
			std::cout << "fail to set stream open mode" << std::endl;
		}
	}
	else
	{
		std::cout << "fail to get port" << std::endl;
	}
}


//实时视频码流数据获取 回调函数
void CALLBACK g_RealDataCallBack_V30(LONG lPlayHandle, DWORD dwDataType, BYTE* pBuffer, DWORD dwBufSize, void* pUser)
{

	if (dwDataType == NET_DVR_STREAMDATA)//码流数据
	{
		if (dwBufSize > 0 && g_nPort != -1)
		{
			if (!PlayM4_InputData(g_nPort, pBuffer, dwBufSize))
			{
				std::cout << "fail input data" << std::endl;
			}
			else
			{
				std::cout << "success input data" << std::endl;
			//这里也可以存图
			/*static int count = 0;
			count += 1;
			string name = to_string(count) + ".jpg";
			cout << "g_BGRImage: " << g_BGRImage.empty() << "========" << name << endl;
			if (!g_BGRImage.empty()) {
			imwrite("D:\\桌面文件\\save_imgsdk\\" + name, g_BGRImage);
			}*/
			}

		}
	}
}

int main()
{
	//------------------------------
	// 初始化
	NET_DVR_Init();
	// 设置连接时间与重连时间
	NET_DVR_SetConnectTime(2000, 1);
	NET_DVR_SetReconnect(10000, true);

	//------------------------------
	// 登录
	NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 };
	
	
	string CameraIPAddress = "172.16.100.223";
	string CameraUserName = "admin";
	string CameraPassword = "123456";

	struLoginInfo.bUseAsynLogin = 0;  // 同步登录方式
	struLoginInfo.wPort = 8000; //设备服务端口
	strcpy_s(struLoginInfo.sDeviceAddress, CameraIPAddress.c_str()); //设备IP地址
	strcpy_s(struLoginInfo.sUserName, CameraUserName.c_str()); //设备登录用户名
	strcpy_s(struLoginInfo.sPassword, CameraPassword.c_str()); //设备登录密码

	LONG lUserID;
	//设备信息, 输出参数
	NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 };
	lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
	if (lUserID < 0)
	{
		cout << "Login error: " << NET_DVR_GetLastError() << endl;;
		NET_DVR_Cleanup();
		return -1;
	}
	else {
		cout << "Login success!" << endl;
	}

	getPort();

	//启动预览并设置回调数据流
	struPlayInfo.hPlayWnd = NULL; //需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
	struPlayInfo.lChannel = 1; //预览通道号
	struPlayInfo.dwStreamType = 0; //0-主码流,1-子码流,2-码流 3,3-码流 4,以此类推
	struPlayInfo.dwLinkMode = 0; //0- TCP 方式,1- UDP 方式,2- 多播方式,3- RTP 方式,4-RTP/RTSP,5-RSTP/HTTP
	struPlayInfo.bBlocked = 1; //0- 非阻塞取流,1- 阻塞取流
	LONG lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL);
	if (lRealPlayHandle < 0)
	{
		//printf(“NET_DVR_RealPlay_V40 error\n”);
		NET_DVR_Logout(lUserID);
		NET_DVR_Cleanup();
		return -1;
	}
	//Sleep(1000); //测试1秒能存几张
	system("pause");
	return 0;
}

参考的sdk:
海康相机sdk,双目视觉,opencv,人工智能,c++,海康威视

第二种使用NET_DVR_JPEGPARA保存图像:

这部分代码已经打包上传,其中需要修改的部分

//使用海康的SDK抓取图像
 HKSDK_LIB_API int __stdcall  playCapture(void* user,int count, Mat &save_image_l,Mat &save_image_r)
{
	//外部多线程使用
	LPMyStruct stru = (LPMyStruct)user;

	//启动预览并设置回调数据流
	NET_DVR_PREVIEWINFO struPlayInfo = { 0 };
	struPlayInfo.hPlayWnd = NULL;         //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
	struPlayInfo.lChannel = stru->channel;       //预览通道号
	struPlayInfo.dwStreamType = 0;       //0-主码流,1-子码流,2-码流3,3-码流4,以此类推
	struPlayInfo.dwLinkMode = 0;       //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
	struPlayInfo.bBlocked = 1;       //0- 非阻塞取流,1- 阻塞取流

	LPNET_DVR_JPEGPARA JpegPara = new NET_DVR_JPEGPARA;
	JpegPara->wPicQuality = 0;
	JpegPara->wPicSize = 70;
	int w = 2560;
	int h = 1440;
	char* Jpeg = new char[w * h];
	DWORD len = w * h;
	LPDWORD Ret = 0;
	if (!NET_DVR_SetCapturePictureMode(BMP_MODE))
	{
		cout << "Set Capture Picture Mode error!" << endl;
		cout << "The error code is " << NET_DVR_GetLastError() << endl;
	}
	vector<char>data(w * h);
	
	bool capture = NET_DVR_CaptureJPEGPicture_NEW(stru->lUserId, struPlayInfo.lChannel, JpegPara, Jpeg, len, Ret);
	if (!capture)
	{
		printf("Error: NET_DVR_CaptureJPEGPicture_NEW = %d", NET_DVR_GetLastError());
		return -1;
	}
	for (int i = 0; i < w * h; i++)
		data[i] = Jpeg[i];

	if(stru->channel==1){
		save_image_l = imdecode(Mat(data), 1);
	}
	if (stru->channel == 2) {
		save_image_r = imdecode(Mat(data), 1);
	}
	
	

	

	return 0;
}

此时save_image_r 表示的就是一个Mat了,主要修改包括:
(1)LPNET_DVR_JPEGPARA
从这一部分开始,和sdk提供的预览方式有所区别,主要用NET_DVR_CaptureJPEGPicture_NEW替换了NET_DVR_RealPlay_V40函数
其中LPNET_DVR_JPEGPARA类提供了一些配置,包括图像大小,图像质量等。

4 完整C++代码工程

完整的代码工程点击头像获取资源,可以直接部署使用,我这里相机有两个通道图,所以拿到了两个图。

5 参考

[1] 海康威视SDK文档 https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10
[2]https://blog.csdn.net/u013832707/article/details/103405278
[3]https://blog.csdn.net/xiaojunjun200211/article/details/122237091文章来源地址https://www.toymoban.com/news/detail-765026.html

到了这里,关于海康威视监控相机的SDK与opencv调用(非工业相机)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (一)Qt+OpenCV调用海康工业相机SDK示例开发

    提示:这里是该系列文章的所有文章的目录 第一章: (一)Qt+OpenCV调用海康工业相机SDK示例开发 第二章: (二)Qt多线程实现海康工业相机图像实时采集 近期在Qt环境下进行海康工业相机的使用开发,发现海康提供的示例没有Qt的demo,而其中有基于MFC框架的示例,所以在这

    2024年02月03日
    浏览(50)
  • 海康威视相机-LINUX SDK 开发

    相机: MV-CS020-10GC 系统:UBUNTU 22.04 语言:C++ 工具:cmake 海康官网下载SDK 运行下面的命令进行安装 安装完成后从在/opt/MVS 路径下就有了相关的库,实际上我们开发的时候只需要lib和include。有兴趣的同学也可以尝试以下Samples的例子。make一下就能生成可执行文件。如果make报错

    2024年02月11日
    浏览(29)
  • 海康威视相机SDK二次开发(JAVA语言)

    前言 有个项目需要使用java程序读取海康威视的相机图片。相机通过以太网连接服务器,部署在服务器上的java程序将相机拍摄的画面保存在指定路径下。 海康威视提供了sdk开发包,可以在官网中下载,windows和linux系统都有。但是开发包中给出的示例代码,无法满足实际需要,

    2024年04月29日
    浏览(30)
  • 基于海康SDK实现Python调用海康威视网络摄像头

    本文参考博客,写得很好: Python调用海康威视网络相机之——python调用海康威视C++的SDK Python调用海康威视网络相机C++的SDK 写本文的目的,也是快速复盘,所以没有很详细 保存视频流到本地可参考下一篇:基于海康SDK实现Python保存海康威视网络摄像头拍摄的视频 Windows11 Vis

    2024年02月02日
    浏览(45)
  • Python海康威视SDK实现实时预览:快速构建高效视频监控系统

    Python海康威视SDK实现实时预览:快速构建高效视频监控系统 在当今社会,安全问题越来越受到人们的关注,越来越多的企业和机构开始建设视频监控系统。而Python作为一种高效、易用的编程语言,已经成为了许多开发人员的首选。本文将介绍如何使用Python海康威视SDK来实现实

    2024年02月14日
    浏览(32)
  • 海康威视工业相机Linux SDK开发指南详细步骤(Ubuntu20.04+单目、双目相机单次、连续拍照)

    由于实验需要使用双目相机同步采集图像,实验室准备的设备是海康威视的工业相机,对其进行二次开发,其中花了大部分时间查找资料,以及代码进行反复调试,最后到达了想要的效果,并写博客记录一下。 首先是资料的查找,我们要注意的是海康威视一共有两个官网,一

    2024年02月16日
    浏览(58)
  • opencv调用海康威视工业摄像头

    opencv调用海康威视工业摄像头需要用到官方接口VideoCapture() 接口:cv2.VideoCapture() 作用:获取本地目录下的视频文件或者使用本电脑的摄像头获取实时数据;  “0” ,调用的是本地电脑摄像头 “1” ,调用的是外接摄像头 打开MVS  正常设置使画面正常  然后找到宽度和长度

    2024年02月13日
    浏览(30)
  • C# 开源SDK 工业相机库 调用海康相机 大恒相机

    c# 相机库,含海康、大恒品牌2D相机的常用功能。 底层采用回调+信号量模式封装 ,最大程度减小线程资源,提高采图效率。 开源地址 :https://gitee.com/laomaogu/mgcamctrl 现只兼容了大恒和海康,都是常用的 其他相机,看我老板啥时候换品牌吧,或者换老板? 当然如果小伙伴感兴

    2024年04月26日
    浏览(26)
  • openCV 多线程调用多个海康威视摄像头(避免画面不同步),进行人脸识别

    1、创建多个线程来拉取不同的视频流,不使用多线程的话,所有的视频流就在排一个队,会出现画面不同步的情况 代码: 2、使用numpy将多个画面放在同一个frame中,图像就是矩阵,numpy是用来处理矩阵的类 代码:  进行人脸识别,网不好帧率太低

    2024年04月25日
    浏览(81)
  • 海康工业相机SDK + OpenCV实例(4):相机参数设置详解

    前文海康工业相机SDK + OpenCV实例(3):相机初始化Bug调试讲述了相机初始化可能遇到的问题。本文讲解海康工业相机设置参数的相关接口,其中,会重点讲解 自动曝光时间调整亮度 , 图像对比度调整 。 海康SDK提供一系列参数设置的接口,本节主要讲解几个万能接口的使用,

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包