#include "hd_mvcamera_module.h" std::mutex moduleMutex;//掉线锁 int reconnectCount = 0; int SearchDevice(); void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0); //0106 断连提示 void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) { mv_Status = "disconnect"; qDebug() << "[Error] " << " MV camera disconnects!trying to reconnect"; //moduleMutex.lock(); reconnectCount++; //消除句柄关闭相机 MV_CC_StopGrabbing(handle); MV_CC_CloseDevice(handle); MV_CC_DestroyHandle(handle); //尝试重连 while (1) { SearchDevice(); unsigned char* serialNumber = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chSerialNumber; string userName = static_cast((LPCSTR)serialNumber); qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName); if (handle != NULL) { MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]); int nRet = MV_CC_OpenDevice(handle); ////触发模式 MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); // //加载用户集 nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); if (MV_OK != nRet) { qDebug() << "Set UserSetSelector fail! nRet " << nRet; } // ch:注册抓图回调 | en:Register image callback MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 nRet = MV_CC_RegisterExceptionCallBack(handle, ExceptionCB, NULL);//注册报警回调 MV_CC_StartGrabbing(handle); //moduleMutex.unlock(); break; } _sleep(100); } } int RGB2BGR(unsigned char* pRgbData, unsigned int nWidth, unsigned int nHeight) { if (NULL == pRgbData) { return MV_E_PARAMETER; } for (unsigned int j = 0; j < nHeight; j++) { for (unsigned int i = 0; i < nWidth; i++) { unsigned char red = pRgbData[j * (nWidth * 3) + i * 3]; pRgbData[j * (nWidth * 3) + i * 3] = pRgbData[j * (nWidth * 3) + i * 3 + 2]; pRgbData[j * (nWidth * 3) + i * 3 + 2] = red; } } return MV_OK; } Hd_MvCamera_module* create() { qDebug() << "[INFO] " << "Hd_MvCamera_module create success!"; return new Hd_MvCamera_module; } void destory(Hd_MvCamera_module* ptr) { if (ptr) { delete ptr; ptr = nullptr; } qDebug() << "[INFO] " << "Hd_MvCamera_module destory success!"; } /// /// 回调取图 /// void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0) { double time_Start = (double)clock(); if (pFrameInfo0) { //获取的是单通道灰度图 if (pFrameInfo0->enPixelType == PixelType_Gvsp_Mono8)//获取当前采集到的图像格式 { srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC1, pData0); } //获取的是RGB8图 else if (pFrameInfo0->enPixelType == PixelType_Gvsp_RGB8_Packed) { RGB2BGR(pData0, pFrameInfo0->nWidth, pFrameInfo0->nHeight); srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0); //cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色 } else if (pFrameInfo0->enPixelType == PixelType_Gvsp_HB_YUV422_YUYV_Packed) { srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC2, pData0); cv::cvtColor(srcImage, srcImage, cv::COLOR_YUV2BGR_UYVY); } //获取的是yuv或bayer图 else if (pFrameInfo0->enPixelType == PixelType_Gvsp_YUV422_Packed || pFrameInfo0->enPixelType == PixelType_Gvsp_BayerRG8) { MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined; enDstPixelType = PixelType_Gvsp_BGR8_Packed; unsigned int nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3; unsigned char* pConvertData = (unsigned char*)malloc(nConvertDataSize); if (NULL == pConvertData) { printf("malloc pConvertData1 fail!\n"); m_flag = true; srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0); return; } MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 }; stConvertParam.nWidth = pFrameInfo0->nWidth; stConvertParam.nHeight = pFrameInfo0->nHeight; stConvertParam.pSrcData = pData0; stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; stConvertParam.enDstPixelType = enDstPixelType; stConvertParam.pDstBuffer = pConvertData; stConvertParam.nDstBufferSize = nConvertDataSize; int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam); if (MV_OK == nRet) { srcImage = cv::Mat::zeros(cv::Size(pFrameInfo0->nWidth, pFrameInfo0->nHeight), CV_8UC3); memcpy(srcImage.data, stConvertParam.pDstBuffer, nConvertDataSize); //Mat mysrcImage = cv::Mat(mypFrameInfo->nHeight, mypFrameInfo->nWidth, CV_8UC3, stConvertParam.pDstBuffer); //mysrcImage.copyTo(srcImage); //mysrcImage.release(); stConvertParam = { 0 }; } else { srcImage = cv::Mat(0, 0, CV_8UC3).setTo(0); } if (pConvertData) { free(pConvertData); pConvertData = NULL; } } } if (!srcImage.empty()) { m_flag = true; double time_End = (double)clock(); //imwrite("C://" + to_string(clock()) + "X.bmp", srcImage); //统计图片成像时间 qDebug() << "[INFO] " << " srcImage Exist,Time:" << (time_End - time_Start) / 1000.0 << "s" << "--CameraName:" << QString::fromStdString(Username); } pData0 = { 0 }; } //搜索所有设备 int SearchDevice() { memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); // ch:枚举子网内所有设备 | en:Enumerate all devices within subnet int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE || MV_USB_DEVICE, &m_stDevList); for (int i = 0; i < m_stDevList.nDeviceNum; i++) { unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber; string serialNumber = static_cast((LPCSTR)name); if (Username == serialNumber) { index = i; break; } } if (MV_OK != nRet) { return 0; } return -1; } Hd_MvCamera_module::Hd_MvCamera_module() { m_thread = new MyThread; } void CloseDevice() { MV_CC_StopGrabbing(handle); MV_CC_CloseDevice(handle); MV_CC_DestroyHandle(handle); } Hd_MvCamera_module::~Hd_MvCamera_module() { CloseDevice(); if (m_thread) { m_thread->exit(); m_thread->wait(1); delete m_thread; m_thread = nullptr; } qDebug() << "[INFO] " << " delete success!"; } bool Hd_MvCamera_module::sendData(std::vector& mat, QByteArray& data) { QString inputString = QString::fromUtf8(data); if (data == "connect") { data = mv_Status; return true; } int underscorePos = inputString.indexOf('_'); if (underscorePos != -1) { QString command = inputString.left(underscorePos); QString value = inputString.mid(underscorePos + 1); if (command == "userset") return false; else if (command == "exposure") { int nRet = MV_CC_SetFloatValue(handle, "ExposureTime", value.toFloat()); if (nRet != MV_OK) { cout << "exposure set fail!" << inputString.toStdString() << endl; } } } else { if (srcImage.empty()) { return false; } mat.push_back(srcImage); srcImage.release(); } return true; } bool Hd_MvCamera_module::reciveData(std::vector& mat, QByteArray& data) { m_flag = false; Username = data.toStdString(); return true; } bool Hd_MvCamera_module::initParas(QByteArray&) { if (!Username.compare("dummy")) { qDebug() << "[INFO] " << " start" << "--UserName: dummy creat sucess"; return true; } SearchDevice(); unsigned char* serialNumber = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chSerialNumber; string userName = static_cast((LPCSTR)serialNumber); qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName); if (handle != NULL) { MV_CC_StopGrabbing(handle); MV_CC_CloseDevice(handle); MV_CC_DestroyHandle(handle); return false; } //打开相机 MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]); int nRet = MV_CC_OpenDevice(handle); ////触发模式 MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE); MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON); // //加载用户集 nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1"); if (MV_OK != nRet) { qDebug() << "Set UserSetSelector fail! nRet " << nRet; } // ch:注册抓图回调 | en:Register image callback MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志 nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调 if (MV_OK != nRet) return false; nRet = MV_CC_RegisterExceptionCallBack(handle, ExceptionCB, NULL);//注册报警回调 if (MV_OK != nRet) return false; MV_CC_StartGrabbing(handle); return true; } bool Hd_MvCamera_module::run() { qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username); try { m_thread->start(); int reconnectSign = reconnectCount; while (true) { if(reconnectCount!= reconnectSign) m_thread->start(); if (m_flag) { break; } QThread::msleep(1); } m_flag = false; } catch (QString ev) { qDebug() << "[Error] " << " ev:" << ev; } qDebug() << "[INFO] " << __LINE__ << " run end"; return true; } void MyThread::run() { MV_CC_SetCommandValue(handle, "TriggerSoftware"); }