1. 引言
在工业自动化、质量检测以及其他机器视觉领域,相机采集与图像处理的系统非常关键。本项目结合了 Qt 框架和 Halcon 库,配合 海康威视相机SDK,实现了一个完整的相机图像采集与处理系统。该系统不仅能够采集高质量图像,还支持实时显示和处理。
源码
通过网盘分享的文件:Qt 与Halcon联合开发八: 结合Qt与Halcon实现海康相机采图显示(附源码)
链接: https://pan.baidu.com/s/1mdb28C4MzN1b4-XK918Beg?pwd=jkcf 提取码: jkcf
2. 软件架构
本软件系统的架构主要分为以下几个模块:
- 相机控制模块:通过
Camera
和HikCamera
类实现对相机的控制,包括相机初始化、打开、关闭、采集等。 - 图像数据管理模块:通过
ImageData
类来管理图像数据的缓存、存取和处理。 - 线程处理模块:利用
IThread
类来处理图像采集线程,从图像缓存中提取数据并显示。 - 用户界面模块:通过
MainWindow
类为用户提供交互界面,控制相机的启动与停止,查看图像处理结果等。
3. 核心模块与实现
3.1 相机回调机制
相机回调机制是相机与软件之间的重要通信桥梁。每当相机采集到新图像时,相机回调函数被触发。以下是海康相机的图像回调函数的实现:
void __stdcall ImageCallBack(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser) {
HikCamera* camera = static_cast<HikCamera*>(pUser);
HalconCpp::HObject ho_Image;
int ImageWidth = pFrameInfo->nWidth;
int ImageHeight = pFrameInfo->nHeight;
switch (pFrameInfo->enPixelType) {
case PixelType_Gvsp_Mono8:
HalconCpp::GenImage1(&ho_Image, "byte", ImageWidth, ImageHeight, reinterpret_cast<Hlong>(pData));
break;
case PixelType_Gvsp_RGB8_Packed:
HalconCpp::GenImageInterleaved(&ho_Image, reinterpret_cast<Hlong>(pData), "rgb",
ImageWidth, ImageHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
break;
case PixelType_Gvsp_BayerRG8:
HalconCpp::GenImage1(&ho_Image, "byte", ImageWidth, ImageHeight, reinterpret_cast<Hlong>(pData));
HalconCpp::CfaToRgb(ho_Image, &ho_Image, "bayer_rg", "bilinear");
break;
default:
HalconCpp::GenImageConst(&ho_Image, "byte", ImageWidth, ImageHeight);
break;
}
if (!camera->getImageData()->addImageData(0, ho_Image)) {
camera->sendErrorsMsgs(camera->getImageData()->getLastErrorMsg() + QString(" -相机#%1").arg(camera->getCameraIndex()));
}
}
此回调函数将原始图像数据转化为 Halcon 图像对象,并存储到 ImageData
的缓存区中。每次新图像采集完成后,该函数被触发。
3.2 图像数据存取:ImageData
类
ImageData
类负责管理图像数据的缓存区。每当新图像采集到时,数据会被加入缓存区,通过多队列管理保证图像数据的高效存取。
class ImageData {
public:
bool addImageData(const int index, const HalconCpp::HObject& ho_Image);
int getImageData(const int index, HalconCpp::HObject* ho_Image);
void clearImageData();
};
- addImageData:向指定队列添加图像数据,如果缓存队列已满,则返回错误信息。
- getImageData:从指定队列获取最新的图像数据。如果队列为空,线程将等待图像数据到来。
3.3 图像显示:IThread
类
图像显示由 IThread
类在独立线程中完成。线程持续从 ImageData
缓存区获取图像数据并将其显示在用户界面上。
void IThread::run() {
while (m_isRun) {
HalconCpp::HObject ho_Image;
switch (m_imgData->getImageData(m_imgIndex, &ho_Image)) {
case ImageData::NoImageData:
m_imgData->wait(m_imgIndex);
continue;
case ImageData::ExistDataButObtainFailed:
emit errors(m_cameraIndex, m_imgData->getLastErrorMsg() + QString(" -相机#%1").arg(m_cameraIndex));
m_isRun = false;
continue;
case ImageData::ExistDataButObtainWithProblem:
break;
case ImageData::ExistDataAndObtainSucced:
break;
}
// 图像显示
HalconCpp::HTuple hv_w, hv_h;
HalconCpp::GetImageSize(ho_Image, &hv_w, &hv_h);
HalconCpp::SetPart(m_windowHandle, 0, 0, hv_h - 1, hv_w - 1);
HalconCpp::DispObj(ho_Image, m_windowHandle);
}
}
图像通过 HalconCpp::DispObj
方法显示在 Qt 窗体上。
3.4 GUI 界面控制:MainWindow
类
MainWindow
类提供了用户交互界面,用户可以通过界面按钮启动或停止相机的图像采集。界面与线程进行通信,实时显示图像。
void MainWindow::createImageBase() {
m_camera = new HikCamera(0, ui->L1->text());
m_camera->setCameraImageFormat(Camera::ImageFormat::RGB8);
m_camera->setCameraType(Camera::CameraType::GIGE);
m_camera->setCameraQueneNumber(3);
m_camera->openCamera(Camera::OpenHardWare);
m_ithread = new IThread();
if (!m_ithread->bind(m_camera, hv_window)) {
writeRunTimeMsgs("处理线程创建失败", JKCF::Error);
return;
}
m_ithread->start();
}
在 createImageBase
方法中,首先初始化相机对象,然后绑定图像处理线程。图像处理线程将开始采集和显示图像。
4. 流程图:从相机到用户界面的图像流转
以下是从相机到用户界面显示的完整流程图:
5. 总结
本系统通过 Qt 和 Halcon 库,结合 海康威视相机SDK,实现了图像采集、处理、显示的完整流程。通过回调机制,系统能够实时接收相机采集到的图像数据,并通过独立的图像处理线程进行显示。模块化设计保证了系统的灵活性和可扩展性,可以适应不同的图像处理需求和相机设备。