当前位置: 首页 > news >正文

MFC,C++,海康SDK,回调,轮询

二次开发,但是找遍了所有的技术文档,都没有找到实现回调取图的完整流程的教程,文档。痛苦不堪,虽然轮询取图在技术文档中实现了,但是还是需要将其与其他很多功能分开。特此,本文将再次简单记录一下实现的过程。

1.一定要使用面向对象的方式。

创建一个相机类和一个主框架类,这里直接在其技术文件中可以找到复制粘贴即可。

然后现在讲述回调实现的源码。轮询技术文档提供,不赘述.

1. 修改对话框类头文件

首先在CImage_GrabDlg.h中添加必要的成员变量和函数声明:

// Image_GrabDlg.h
class CImage_GrabDlg : public CDialogEx
{// ... 其他已有代码protected:// 用于显示图像的静态控件句柄HWND m_hwndDisplay;// 图像数据相关unsigned char* m_pSaveImageBuf;unsigned int m_nSaveImageBufSize;CRITICAL_SECTION m_hSaveImageMux;MV_FRAME_OUT_INFO_EX m_stImageInfo;// 回调函数声明static void __stdcall ImageCallBackEx(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser);void OnImageCallBack(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo);// 初始化函数void DisplayWindowInitial();// ... 其他已有成员
};

2. 修改对话框类实现文件

2.1 初始化部分

// Image_GrabDlg.cpp
CImage_GrabDlg::CImage_GrabDlg(CWnd* pParent /*=NULL*/): CDialogEx(IDD_IMAGE_GRAB_DIALOG, pParent), m_pcMyCamera(NULL), m_nDeviceCombo(0), m_bOpenDevice(FALSE), m_bStartGrabbing(FALSE), m_hGrabThread(NULL), m_bThreadState(FALSE), m_nTriggerMode(MV_TRIGGER_MODE_OFF), m_pSaveImageBuf(NULL), m_nSaveImageBufSize(0)
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);memset(&m_stImageInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));InitializeCriticalSection(&m_hSaveImageMux);
}CImage_GrabDlg::~CImage_GrabDlg()
{DeleteCriticalSection(&m_hSaveImageMux);if (m_pSaveImageBuf){free(m_pSaveImageBuf);m_pSaveImageBuf = NULL;}
}

2.2 回调函数实现

// 静态回调函数
void __stdcall CImage_GrabDlg::ImageCallBackEx(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser)
{if (!pData || !pFrameInfo || !pUser){return;}CImage_GrabDlg* pThis = (CImage_GrabDlg*)pUser;pThis->OnImageCallBack(pData, pFrameInfo);
}// 实际处理回调的成员函数
void CImage_GrabDlg::OnImageCallBack(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo)
{// 保存图像数据EnterCriticalSection(&m_hSaveImageMux);if (NULL == m_pSaveImageBuf || pFrameInfo->nFrameLen > m_nSaveImageBufSize){if (m_pSaveImageBuf){free(m_pSaveImageBuf);m_pSaveImageBuf = NULL;}m_pSaveImageBuf = (unsigned char*)malloc(pFrameInfo->nFrameLen);if (m_pSaveImageBuf == NULL){LeaveCriticalSection(&m_hSaveImageMux);return;}m_nSaveImageBufSize = pFrameInfo->nFrameLen;}memcpy(m_pSaveImageBuf, pData, pFrameInfo->nFrameLen);memcpy(&m_stImageInfo, pFrameInfo, sizeof(MV_FRAME_OUT_INFO_EX));LeaveCriticalSection(&m_hSaveImageMux);// 在UI线程中更新显示if (m_hwndDisplay){MV_CC_IMAGE stImageData = {0};stImageData.nWidth = pFrameInfo->nWidth;stImageData.nHeight = pFrameInfo->nHeight;stImageData.enPixelType = pFrameInfo->enPixelType;stImageData.nImageLen = pFrameInfo->nFrameLen;stImageData.pImageBuf = pData;m_pcMyCamera->DisplayOneFrame(m_hwndDisplay, &stImageData);}
}

2.3 开始采集按钮实现

void CImage_GrabDlg::OnBnClickedButton4()
{if (FALSE == m_bOpenDevice || TRUE == m_bStartGrabbing || NULL == m_pcMyCamera){return;}// 注册回调函数int nRet = MV_CC_RegisterImageCallBackEx(m_pcMyCamera->outinterface(), CImage_GrabDlg::ImageCallBackEx, this);if (MV_OK != nRet){ShowErrorMsg(TEXT("Register image callback fail"), nRet);return;}// 设置采集模式为连续采集nRet = m_pcMyCamera->SetNetTransMode(MV_TRIGGER_MODE_OFF);if (MV_OK != nRet){ShowErrorMsg(TEXT("Set trigger mode fail"), nRet);return;}// 开始采集nRet = m_pcMyCamera->StartGrabbing();if (MV_OK != nRet){ShowErrorMsg(TEXT("Start grabbing fail"), nRet);return;}m_bStartGrabbing = TRUE;
}

2.4 停止采集按钮实现

void CImage_GrabDlg::OnBnClickedButton6()
{if (FALSE == m_bOpenDevice || FALSE == m_bStartGrabbing || NULL == m_pcMyCamera){return;}// 停止采集int nRet = m_pcMyCamera->StopGrabbing();if (MV_OK != nRet){ShowErrorMsg(TEXT("Stop grabbing fail"), nRet);return;}// 注销回调函数nRet = MV_CC_RegisterImageCallBackEx(m_pcMyCamera->outinterface(), NULL, NULL);if (MV_OK != nRet){ShowErrorMsg(TEXT("Unregister image callback fail"), nRet);}m_bStartGrabbing = FALSE;
}

3. 显示窗口初始化

void CImage_GrabDlg::DisplayWindowInitial()
{CWnd *pWnd = GetDlgItem(IDC_DISPLAY_STATIC);if (pWnd){m_hwndDisplay = pWnd->GetSafeHwnd();// 设置静态控件样式为SS_BITMAP,用于显示图像pWnd->ModifyStyle(0, SS_BITMAP);// 初始化显示黑色背景CRect rect;pWnd->GetClientRect(&rect);CDC *pDC = pWnd->GetDC();CBitmap bitmap;bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());pWnd->SetBitmap((HBITMAP)bitmap.Detach());pWnd->ReleaseDC(pDC);}
}

4. 资源文件修改

在对话框资源中添加一个静态文本控件,ID设置为IDC_DISPLAY_STATIC,用于显示图像。调整其大小以适应图像显示需求。

5. 使用说明

  1. 点击"查找设备"按钮枚举可用相机设备

  2. 选择设备后点击"打开设备"按钮连接相机

  3. 点击"开始采集"按钮开始接收图像并在静态控件中显示

  4. 点击"停止采集"按钮停止图像采集

  5. 点击"关闭设备"按钮断开相机连接

注意事项

  1. 图像显示使用了静态控件的SS_BITMAP样式,确保控件足够大以显示完整图像

  2. 使用了临界区保护图像数据,确保多线程安全

  3. 回调函数中直接调用显示函数,确保图像实时显示

  4. 需要处理图像格式转换,如果相机输出的像素格式与显示要求不符

这个方案利用了海康威视相机SDK的回调机制,在回调函数中获取图像数据并显示在MFC对话框的静态控件中,实现了高效的图像采集和显示功能。

最后注意,上述一定是在类中实现的,如果没有类的基础,上述可能对你没有什么帮助,当然如果自己实在使用不上上面给出的思路,可以在评论区,评论,博主看到会简答。

http://www.dtcms.com/a/338652.html

相关文章:

  • 借助AI将infoNES移植到HarmonyOS平台的详细方案介绍
  • “道法术器” 思维:解析华为数字化转型
  • Springboot使用Selenium+ChormeDriver在服务器(Linux)端将网页保存为图片或PDF
  • 如何在未来进一步推动NLP技术的发展?
  • Java高级面试实战:Spring Boot微服务与Redis缓存整合案例解析
  • 【牛客刷题】岛屿数量问题:BFS与DFS解法深度解析
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第二十六讲)
  • 控制对文件的访问:Linux 文件系统权限管理总结
  • 基于VLM 的机器人操作视觉-语言-动作模型:综述 2
  • JavaSSM框架从入门到精通!第二天(MyBatis(一))!
  • 走进数字时代,融入数字生活,构建数字生态
  • 可以一键生成PPT的AI PPT工具(最新整理)
  • Flink Checkpoint 原理深度剖析与作用讲解(flink面试高频问题)
  • 在Ubuntu上安装并使用Vue2的基本教程
  • Flink Stream API - 源码二开详细实现
  • 测试 Next.js 应用:工具与策略
  • React Native 与 UniApp 对比
  • React native Navigation 详解
  • npm下的scratch(少儿编程篇)
  • 接口自动化测试持续集成CI/CD(Jenkins)
  • 应用缓存不止是Redis!——亿级流量系统架构设计系列
  • Ansible 角色管理
  • RabbitMQ处理流程详解
  • 基于NB-IOT的智慧路灯系统的设计与实现/基于stm32的太阳能路灯系统的设计与实现#单片机#物联网#嵌入式开发
  • 华金证券携手非凸科技,共话AI赋能交易新未来
  • BeanUtils拷贝大对决:Spring与Apache Commons的差异与妙用
  • 基于多级缓存架构的Redis集群与Caffeine本地缓存实战经验分享
  • Node.js完整安装配置指南(包含国内镜像配置)
  • 第5章 高级状态管理
  • webrtc弱网-GoogCcNetworkController类源码分析与算法原理