栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

海康工业相机SDK注册回调函数C++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

海康工业相机SDK注册回调函数C++

有一个小型的工业相机,

主管安排学习下工业相机的SDK的使用,做一个实时采图的demo 

相机客户端下载:海康机器人-机器视觉-下载中心 (hikrobotics.com)

应该在后面几页里,叫机器视觉工业相机客户端MVS

开始我去了海康官网下的网络设备SDK,

后面看了大佬们的博客才知道,这个是要工业相机的SDK,

下载的是MVS软件,有相机客户端,相机客户端的使用手册及SDK文档和例子

比如用visual studio开发的例子,在此路径下

MVS/Development/Documentations/示例程序说明VS2008.pdf

里面也说了对应visual studio例子的位置

MVSDevelopmentSamplesVCVS

MVS相机客户端初始配置是把相机IP设为和连接的WLAN同网段的静态IP,

如WLAN的IP为:192.168.102.104

设置的相机IP为:192.168.102.2

连接相机,采集图像,可以采图,开始是黑白色的,

图像处理中的像素格式是Mono,改为RGB就是彩色的了,

然后退出该客户端,去参照例子做一个实时采图的demo

官方例子BasicDemo就是一个实时采图的例子,

它用的好像是主动取流,多线程的方式,

主管说要再弄个注册回调取流的demo,

就把官方demo中多线程的部分删掉,

又参照了众多大佬的博客,

最后倒是可以采图了,但保存图片有问题,

我感觉自己拼凑的回调取流有些问题,

又继续网上搜罗,看到有说官方例子里有回调取流的demo,

不过是c#的,在这个位置MVSDevelopmentSamplesC#MultipleDemo

代码文件MultiDemo.cs,还是有些用处的

参照着改了改,保存图片这里仍未解决

又参照了大佬的博客

海康相机SDK开发in VS2015+Qt5 - onefish51 - 博客园 (cnblogs.com)

保存图片可以了,但多次保存还是会有报错,比如Access violation writing location,

又去参照BasicDemo里的改了改,看的有些晕,

但是实时采图,保存图片都可以了,也可以多次保存图片了

放一些我感觉关键地方的代码吧,就是在BasicDemo上改的:

开始采集这里注册回调函数

// ch:按下开始采集按钮 | en:Click Start button
void CHIKBasicDemoCallBackDlg::OnBnClickedStartGrabbingButton()
{
	if (FALSE == m_bOpenDevice || TRUE == m_bStartGrabbing || NULL == m_pcMyCamera)
	{
		return;
	}

	memset(&m_stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));

	//注册回调函数 
	int nRet = m_pcMyCamera->RegisterImageCallBack(ImageCallBackEx, this);
	if (nRet != MV_OK)
	{
		ShowErrorMsg(TEXT("Register image callback fail"), nRet);
		return;
	}

	nRet = m_pcMyCamera->StartGrabbing();

	if (MV_OK != nRet)
	{
		ShowErrorMsg(TEXT("Start grabbing fail"), nRet);
		return;
	}
	m_bStartGrabbing = TRUE;
	EnableControls(TRUE);

	return;
}

注册回调函数的具体实现,

在头文件中该回调函数声明为静态的了,参照大佬的博客弄的

//声明回调函数为静态函数
static void __stdcall ImageCallBackEx(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser);

具体实现, 

void __stdcall CHIKBasicDemoCallBackDlg::ImageCallBackEx(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser)
{
	CHIKBasicDemoCallBackDlg* callback_dlg = (CHIKBasicDemoCallBackDlg*)pUser;

	// ch:抓取的帧数
	++callback_dlg->m_nFrames;

	//ch:判断是否需要保存图片
	if (callback_dlg->m_bSaveImg)
	{
		callback_dlg->SaveImage(pData, *pFrameInfo);
		callback_dlg->m_bSaveImg = false;
	}

	//显示实时图像
	MV_DISPLAY_FRAME_INFO stDisplayInfo = {0};
	stDisplayInfo.hWnd = callback_dlg->m_hwndDisplay;
	stDisplayInfo.pData = pData;
	stDisplayInfo.nDataLen = (*pFrameInfo).nFrameLen;
	stDisplayInfo.nWidth = (*pFrameInfo).nWidth;
	stDisplayInfo.nHeight = (*pFrameInfo).nHeight;
	stDisplayInfo.enPixelType = (*pFrameInfo).enPixelType;

	callback_dlg->m_pcMyCamera->DisplayOneFrame(&stDisplayInfo);	
}

头文件与保存图片相关的变量

bool						m_bSaveImg;					//	ch:保存图片标志位
unsigned int				m_nBufSizeForSaveImage;
unsigned char*				m_pBufForSaveImage;			// ch:用于保存图像的缓存 

保存图片,

//ch:保存图片
void CHIKBasicDemoCallBackDlg::SaveImage(unsigned char* pData, MV_FRAME_OUT_INFO_EX pFrameInfo)
{
	unsigned int nSaveImageNeedSize = pFrameInfo.nFrameLen * 3 + 2048;
	if (NULL == m_pBufForSaveImage || m_nBufSizeForSaveImage < nSaveImageNeedSize)
	{
		if (m_pBufForSaveImage)
		{
			free(m_pBufForSaveImage);
			m_pBufForSaveImage = NULL;
		}

		m_pBufForSaveImage = (unsigned char*)malloc(nSaveImageNeedSize);
		if (NULL == m_pBufForSaveImage)
		{
			ShowErrorMsg(TEXT("Distributed Save failed"), 0 );
		}
		m_nBufSizeForSaveImage = nSaveImageNeedSize;
	}

	MV_SAVE_IMAGE_PARAM_EX pstSaveFileParam = {};
	memset(&pstSaveFileParam, 0, sizeof(MV_SAVE_IMAGE_PARAM_EX));

	pstSaveFileParam.enImageType = m_nSaveImageType;				// ch:需要保存的图像类型 | en:Image format to save
	pstSaveFileParam.enPixelType = pFrameInfo.enPixelType;		
	pstSaveFileParam.nWidth = pFrameInfo.nWidth;					
	pstSaveFileParam.nHeight = pFrameInfo.nHeight;				
	pstSaveFileParam.nDataLen = pFrameInfo.nFrameLen;
	pstSaveFileParam.pData = pData;
	pstSaveFileParam.pImageBuffer = m_pBufForSaveImage;            // ch: 存放图像输出
	pstSaveFileParam.nBufferSize = m_nBufSizeForSaveImage;

	if (m_nSaveImageType == MV_Image_Jpeg)
	{
		pstSaveFileParam.nJpgQuality = 80;
	}

	char chImageName[IMAGE_NAME_LEN] = { 0 };
	if (MV_Image_Jpeg == pstSaveFileParam.enImageType)
	{
		sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d.jpg", pstSaveFileParam.nWidth, pstSaveFileParam.nHeight, pFrameInfo.nFrameNum);
	}
	else if (MV_Image_Bmp == pstSaveFileParam.enImageType)
	{
		sprintf_s(chImageName, IMAGE_NAME_LEN, "Image_w%d_h%d_fn%03d.bmp", pstSaveFileParam.nWidth, pstSaveFileParam.nHeight, pFrameInfo.nFrameNum);
	}

	int nRet = m_pcMyCamera->SaveImage(&pstSaveFileParam);
	if (MV_OK != nRet)
	{
		ShowErrorMsg(TEXT("Save failed"), nRet);
	}
	else
	{
		//将转换之后图片数据保存成文件
		FILE* fp;
		errno_t err =fopen_s(&fp, chImageName, "wb");
		fwrite(m_pBufForSaveImage, 1, pstSaveFileParam.nImageLen, fp);
		fclose(fp);
	}
}

最后感谢各位大佬的博客分享,有你们真好!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025502.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号