V20251030-2.1.1

修复相机取流崩溃的bug。
加快海康相机初始化的速度。
This commit is contained in:
2025-10-30 15:21:58 +08:00
parent 6ab9c1b597
commit d76078959f
10 changed files with 129 additions and 684 deletions
@@ -26,6 +26,16 @@ bool ifRunning = false;
MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表
//MV_GENTL_IF_INFO_LIST m_stIFList;
void CloseDevice();
static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) {
MV_CC_DEVICE_INFO_LIST deviceInfoList;
if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) {
memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST));
}
else {
qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!";
}
return deviceInfoList;
}
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
@@ -94,9 +104,15 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra
//搜索所有设备
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);
if (m_stDevList.nDeviceNum == 0) {
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);
if (MV_OK != nRet)
{
return 0;
}
}
for (int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//SN
@@ -110,10 +126,6 @@ int SearchDevice()
break;
}
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
@@ -387,6 +399,13 @@ bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector<cv::Mat>& mat, QByteArr
bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector<cv::Mat>& mat, QByteArray& data)
{
Q_UNUSED(mat);
if (data.contains("deviceList")) {
auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10));
if (result.nDeviceNum != 0) {
m_stDevList = result;
return true;
}
}
QStringList dataList = QString::fromUtf8(data).split("_");
//2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值
if (data == "rest_newProductIn")
-570
View File
@@ -1,570 +0,0 @@
#include "Hd_CameraModule_HIK_hard_PCIE.h"
#include <QDebug>
using namespace std;
#include <QTextCodec>
QByteArray mv_Status = "connected";//0106 新增相机断联报警
long long index = 0; //相机序号
void* handle;
string Username = "";
bool m_flag = false;
//MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备
bool moduleStatus = true;
QQueue<cv::Mat> queuepic;
//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。
bool ifBreak = false;
//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图
bool ifRunning = false;
MV_GENTL_DEV_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表
MV_GENTL_IF_INFO_LIST m_stIFList;
void CloseDevice();
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
// 如果转换成功,则值为0,如果值大于0,则说明转换失败
QTextCodec::ConverterState state;
// 先尝试使用utf-8的方式把QByteArray转换成QString
QString text = QTextCodec::codecForName("UTF-8")->toUnicode(array.constData(), array.size(), &state);
// 如果转换时无效字符数量大于0,说明编码格式不对
if (state.invalidChars > 0)
{
// 再尝试使用GBK的方式进行转换,一般就能转换正确(当然也可能是其它格式,但比较少见了)
text = QTextCodec::codecForName("GBK")->toUnicode(array);
}
return text;
}
QMutex* n_mutex = new QMutex();
//cv::Mat srcImage;
//是否为标准通信流程:
//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益
int imgCnt = 0;
bool ifStandard = false;
//相机取图超时时间
int getImageTimeOut = 3000;
//总取图数
int imgIndex = 0;
//曝光值列表
QQueue<float> expourseTimeList;
//增益列表
QQueue<float> gainList;
bool IsColor(MvGvspPixelType enType)
{
switch (enType)
{
case PixelType_Gvsp_RGB8_Packed:
case PixelType_Gvsp_YUV422_Packed:
case PixelType_Gvsp_YUV422_YUYV_Packed:
case PixelType_Gvsp_BayerGR8:
case PixelType_Gvsp_BayerRG8:
case PixelType_Gvsp_BayerGB8:
case PixelType_Gvsp_BayerBG8:
case PixelType_Gvsp_BayerGB10:
case PixelType_Gvsp_BayerGB10_Packed:
case PixelType_Gvsp_BayerBG10:
case PixelType_Gvsp_BayerBG10_Packed:
case PixelType_Gvsp_BayerRG10:
case PixelType_Gvsp_BayerRG10_Packed:
case PixelType_Gvsp_BayerGR10:
case PixelType_Gvsp_BayerGR10_Packed:
case PixelType_Gvsp_BayerGB12:
case PixelType_Gvsp_BayerGB12_Packed:
case PixelType_Gvsp_BayerBG12:
case PixelType_Gvsp_BayerBG12_Packed:
case PixelType_Gvsp_BayerRG12:
case PixelType_Gvsp_BayerRG12_Packed:
case PixelType_Gvsp_BayerGR12:
case PixelType_Gvsp_BayerGR12_Packed:
return true;
default:
return false;
}
}
//0106 断线重连
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser);
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0);
//搜索所有设备
int SearchDevice()
{
//MV_CC_Initialize();
/* MV_CC_DEVICE_INFO_LIST stDeviceList;
memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
unsigned int nnRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE, &stDeviceList);
return 1;*/
const char* chCtiPath = "MvFGProducerXoF.cti";//.cti文件路径
int nRet = 0;
nRet = MV_CC_EnumInterfacesByGenTL(&m_stIFList, chCtiPath);
if (nRet != MV_OK)
{
qDebug() << "EnumInterfacsByGenTL fail";
return 0;
}
if (m_stIFList.nInterfaceNum == 0)
{
qDebug() << "No Device";
return 0;
}
// ch:枚举子网内所有设备 | en:Enumerate all devices within subnet
for (int p = 0; p < m_stIFList.nInterfaceNum; p++)
{
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
nRet = MV_CC_EnumDevicesByGenTL(m_stIFList.pIFInfo[p], &m_stDevList);
bool ifHas = false;
for (int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//SN
unsigned char* name = m_stDevList.pDeviceInfo[i]->chSerialNumber;
string userName = static_cast<string>((LPCSTR)name);
if (Username == userName)
{
index = i;
ifHas = true;
break;
}
}
if (ifHas)break;
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
bool connectDevice()
{
//MV_CC_Initialize();
index = -1;
SearchDevice();
if (index == -1)
{
//未匹配到相机
//qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username);
return false;
}
unsigned char* name = m_stDevList.pDeviceInfo[index]->chSerialNumber;
string userName = static_cast<string>((LPCSTR)name);
qDebug() << "[INFO] " << " start" << "--UserName:" << QString::fromStdString(userName);
if (handle != NULL)
{
MV_CC_StopGrabbing(handle);
MV_CC_CloseDevice(handle);
MV_CC_DestroyHandle(handle);
}
//打开相机
MV_CC_CreateHandleByGenTL(&handle, m_stDevList.pDeviceInfo[index]);
int nRet = MV_CC_OpenDevice(handle);
////触发模式
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
// //加载用户集,相机设置应当UserSet1
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, ReconnectDevice, NULL);//断线重连
if (MV_OK != nRet)
return false;
MV_CC_StartGrabbing(handle);
return true;
}
void SetExposureTime(float exposureValue)
{
qDebug() << "[INFO] " << "exposureValue:" << exposureValue;
MV_CC_SetEnumValue(handle, "ExposureAuto", MV_EXPOSURE_AUTO_MODE_OFF);
MV_CC_SetFloatValue(handle, "ExposureTime", exposureValue);
}
void SetGain(float GainValue)
{
qDebug() << "[INFO] " << "GainValue:" << GainValue;
MV_CC_SetEnumValue(handle, "GainAuto", 0);
MV_CC_SetFloatValue(handle, "Gain", GainValue);
}
//0518 断线重连
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser)
{
mv_Status = "disconnect";
qDebug() << "[Error] " << " MV camera disconnects!";
moduleStatus = false;
if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT)
{
//断开连接
CloseDevice();
handle = nullptr;
BOOL bConnected = FALSE;
while (1)
{
Sleep(100);
if (connectDevice() == true)
{
qWarning() << "[Hd_CameraModule_HIK] " << " Hd_CameraModule_HIK create success again! ";
moduleStatus = true;
break;
}
}
}
}
//0106 断连提示
void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) {
mv_Status = "disconnect";
qDebug() << "[Error] " << " MvCameraTL disconnects!";
}
Hd_CameraModule_HIK_hard_PCIE* create()
{
qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!";
return new Hd_CameraModule_HIK_hard_PCIE;
}
void destory(Hd_CameraModule_HIK_hard_PCIE* ptr)
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!";
}
//回调函数;
//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0)
{
Q_UNUSED(pUser0)
int frameNum = 0;
double time_Start = (double)clock();
n_mutex->lock();
cv::Mat srcImage = cv::Mat();
//qDebug() << "[info]" << __FUNCTION__ << " line:" << __LINE__ << "--- start";
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_BGR8_Packed)
{
srcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0);
//cvtColor(srcImage, srcImage, COLOR_RGB2BGR);//导致异色
}
else if (IsColor(pFrameInfo0->enPixelType)) //其它格式彩色图
{
MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined;
enDstPixelType = PixelType_Gvsp_BGR8_Packed;
unsigned char* pConvertData = NULL;
pConvertData = (unsigned char*)malloc(pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3);
if (NULL == pConvertData)
{
printf("malloc pConvertData fail!\n");
}
else
{
unsigned int nConvertDataSize = 0;
nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3;
// ch:像素格式转换 | en:Convert pixel format
MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };
frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number
stConvertParam.nWidth = pFrameInfo0->nWidth; //ch:图像宽 | en:image width
stConvertParam.nHeight = pFrameInfo0->nHeight; //ch:图像高 | en:image height
stConvertParam.pSrcData = pData0; //ch:输入数据缓存 | en:input data buffer
stConvertParam.nSrcDataLen = pFrameInfo0->nFrameLen; //ch:输入数据大小 | en:input data size
stConvertParam.enSrcPixelType = pFrameInfo0->enPixelType; //ch:输入像素格式 | en:input pixel format
stConvertParam.enDstPixelType = enDstPixelType; //ch:输出像素格式 | en:output pixel format
stConvertParam.pDstBuffer = pConvertData; //ch:输出数据缓存 | en:output data buffer
stConvertParam.nDstBufferSize = nConvertDataSize; //ch:输出缓存大小 | en:output buffer size
int nRet = MV_CC_ConvertPixelType(handle, &stConvertParam);
Mat mysrcImage = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, stConvertParam.pDstBuffer);
mysrcImage.copyTo(srcImage);
free(pConvertData);
pConvertData = NULL;
stConvertParam = { 0 };
}
}
}
if (srcImage.empty())
{
srcImage = cv::Mat(5, 5, CV_8UC1).setTo(0);
}
if (ifStandard == false)
{
imgIndex++;
if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()])
SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]);
if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()])
SetGain(gainList[imgIndex % gainList.size()]);
}
queuepic.push_back(srcImage);
m_flag = true;
n_mutex->unlock();
pData0 = { 0 };
imgCnt++;
double time_End = (double)clock();
std::cout << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms"
<< "--CameraName:" << Username << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum << std::endl;
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms"
<< "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum;
}
Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE()
{
//m_thread = new MyThread;
//m_mutex = new QMutex();
}
//关闭设备
void CloseDevice()
{
if (handle == nullptr)
return;
unsigned int nRet = MV_CC_StopGrabbing(handle);
if (nRet == 0) {
MV_CC_CloseDevice(handle);
MV_CC_DestroyHandle(handle);
}
//nRet = MV_CC_CloseDevice(handle);
//nRet = MV_CC_DestroyHandle(handle);
}
Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE()
{
CloseDevice();
if (n_mutex)
{
delete n_mutex;
n_mutex = nullptr;
}
qDebug() << "[INFO] " << " delete success!";
}
//从类中读数据到实例对象
bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector<cv::Mat>& mat, QByteArray& data)
{
if (queuepic.isEmpty())
{
//qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null";
return false;
}
n_mutex->lock();
cv::Mat img = queuepic.dequeue();
mat.push_back(img);
queuepic.clear();
n_mutex->unlock();
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex;
return true;
}
//实例对象把数据写入到类;加载模型后会运行此函数
bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector<cv::Mat>& mat, QByteArray& data)
{
Q_UNUSED(mat);
QStringList dataList = QString::fromUtf8(data).split("_");
//2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值
if (data == "rest_newProductIn")
{
//根据实际项目,设置初始值:曝光、增益,ROI区域等
{
if (expourseTimeList.size() > 0)
SetExposureTime(expourseTimeList[0]);
if (gainList.size() > 0)
SetGain(gainList[0]);
}
if (queuepic.size() > 0)
{
n_mutex->lock();
queuepic.clear();
n_mutex->unlock();
std::cout << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << Username << std::endl;
qWarning() << __FUNCTION__ << " line: " << __LINE__ << "rest_newProductIn , queuePic.size() > 0 ,signal maybe too fast " << QString::fromStdString(Username);
}
if (ifRunning == true)
{
ifBreak = true;
Sleep(10);
}
imgIndex = 0;
return true;
}
else if (dataList.size() > 1) {
if (dataList[0] == "cameraTriggerSignal") {
imgShouldGetVec.clear();
imgShouldGetIndex = 0;
for (int i = 1; i < dataList.size(); i++)
imgShouldGetVec.push_back(dataList[i].toInt());
}
}
else
{
m_flag = false;
expourseTimeList.clear();
gainList.clear();
}
//Username= data.toStdString();
return true;
}
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
bool Hd_CameraModule_HIK_hard_PCIE::initParas(QByteArray& initData)
{
QByteArrayList valueList = initData.split('+');
Username = valueList[0];
imgIndex = 0;
expourseTimeList.clear();
gainList.clear();
if (valueList.size() > 1)
for (int i = 1; i < valueList.size(); i++)
{
QString valuei = byteArrayToUnicode(valueList[i]);
//valuei.prepend(valueList[i]);
if (valuei.contains("expourseTime"))
{
QStringList expourseTimeL = valuei.split('#');
if (expourseTimeL.size() > 1)
for (int j = 1; j < expourseTimeL.size(); j++)
expourseTimeList.enqueue(expourseTimeL[j].toFloat());
}
if (valuei.contains("gain"))
{
QStringList gainL = valuei.split('#');
if (gainL.size() > 1)
for (int j = 1; j < gainL.size(); j++)
gainList.enqueue(gainL[j].toFloat());
}
if (valuei.contains("是否为标准通信流程"))
{
if (valuei.contains("true"))
ifStandard = true;
}
if (valuei.contains("取图超时"))
{
QStringList gainL = valuei.split('#');
if (gainL.size() > 1)
getImageTimeOut = gainL[1].toInt();
if (getImageTimeOut < 50)
getImageTimeOut = 1000;
}
if (valuei.contains("OffsetX"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "OffsetX", valueL[1].toInt());
}
if (valuei.contains("OffsetY"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "OffsetY", valueL[1].toInt());
}
if (valuei.contains("Width"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "Width", valueL[1].toInt());
}
if (valuei.contains("Height"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
MV_CC_SetIntValue(handle, "Height", valueL[1].toInt());
}
}
bool ifOk = connectDevice();
if (ifOk == true)
{
if (expourseTimeList.size() > 0)
SetExposureTime(expourseTimeList[0]);
if (gainList.size() > 0)
SetGain(gainList[0]);
}
imgIndex = 0;
return ifOk;
}
bool Hd_CameraModule_HIK_hard_PCIE::run()
{
qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username);
bool result = false;
ifRunning = true;
ifBreak = false;
try
{
m_flag = false;
int mytime = 0;
int cnt = 0;
while (true)
{
/* if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true)
{
result = false;
break;
}*/
cnt++;
if (queuepic.size() > 0)
{
result = true;
std::cout << "\n gotImg" << std::endl;
break;
}
if (cnt > 2000) {
n_mutex->lock();
//queuepic.push_back(cv::imread("D://Image_20250809202445856.bmp", -1));
queuepic.push_back(cv::Mat(200, 200, CV_8UC3, cv::Scalar(0, 255, 0))); //返回空图
std::cout << "timeout" << std::endl;
n_mutex->unlock();
return true;
}
QThread::msleep(1);
}
//考虑到误触发、漏触发的图,在这里进行设置。
//需要设置曝光时
if (ifStandard == true)
{
imgIndex++;
if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()])
SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]);
if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()])
SetGain(gainList[imgIndex % gainList.size()]);
}
}
catch (QString ev)
{
qDebug() << "[Error] " << " ev:" << ev;
}
qDebug() << "[INFO] " << __LINE__ << " run end";
return result;
}
//相机连接状态:正常连接或断开
bool Hd_CameraModule_HIK_hard_PCIE::checkStatus()
{
//status = moduleStatus;
return moduleStatus;
}
-43
View File
@@ -1,43 +0,0 @@
#ifndef Hd_CameraModule_HIK_hard_PCIE_H
#define Hd_CameraModule_HIK_hard_PCIE_H
#include <QtCore/qglobal.h>
#include <MvCameraControl.h>
#include <CameraParams.h>
#include <Windows.h>
#include <time.h>
#include <QThread>
#include <QQueue>
#include <QMutex>
#include <subModuleBase.h>
using namespace cv;
#pragma execution_character_set("utf-8")
class Hd_CameraModule_HIK_hard_PCIE :public dsModuleBase
{
public:
Hd_CameraModule_HIK_hard_PCIE();
virtual ~Hd_CameraModule_HIK_hard_PCIE();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>& mat, QByteArray& data);
//实例对象把数据写入到类
bool writeData(std::vector<cv::Mat>& mat, QByteArray& data);
bool initParas(QByteArray& initData);
bool run();
bool checkStatus();
private:
std::vector<int> imgShouldGetVec;
int imgShouldGetIndex = 0;
//MyThread *m_thread = nullptr;
//QMutex* m_mutex;
};
extern "C"
{
Q_DECL_EXPORT Hd_CameraModule_HIK_hard_PCIE * create();
Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_PCIE * ptr);
}
#endif // Hd_CameraModule_HIK_hard_H
//Hd_CameraModule_HIK_hard_PCIE
@@ -36,7 +36,16 @@ QString byteArrayToUnicode(const QByteArray array) {
}
return text;
}
static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) {
MV_CC_DEVICE_INFO_LIST deviceInfoList;
if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) {
memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST));
}
else {
qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!";
}
return deviceInfoList;
}
#pragma execution_character_set("utf-8")
QMutex* n_mutex;// = new QMutex();
@@ -93,13 +102,19 @@ bool IsColor(MvGvspPixelType enType)
//搜索所有设备
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_USB_DEVICE , &m_stDevList);
if (m_stDevList.nDeviceNum == 0) {
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);
if (MV_OK != nRet)
{
return 0;
}
}
for (int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//SN
unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber;
unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber;
//userID
//unsigned char* name=m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName;
string userName = static_cast<string>((LPCSTR)name);
@@ -109,21 +124,17 @@ int SearchDevice()
break;
}
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
bool connctDevice()
bool connectDevice()
{
index = -1;
SearchDevice();
if (index == -1)
{
//未匹配到相机
qDebug() << "[Waring] " << "Hd_CameraModule_HIK_soft not match --CameraName:" << QString::fromStdString(Username);
qDebug() << "[Waring] " << "Hd_CameraModule_HIK_hard_USB not match --CameraName:" << QString::fromStdString(Username);
return false;
}
unsigned char* name = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName;
@@ -177,9 +188,9 @@ void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser)
while (1)
{
Sleep(100);
if (connctDevice() == true)
if (connectDevice() == true)
{
qWarning() << "[Hd_CameraModule_HIK_soft] " << " Hd_CameraModule_HIK_soft create success again! ";
qWarning() << "[Hd_CameraModule_HIK_hard_USB] " << " Hd_CameraModule_HIK_hard_USB create success again! ";
moduleStatus = true;
break;
}
@@ -215,20 +226,20 @@ int RGB2BGR(unsigned char* pRgbData, unsigned int nWidth, unsigned int nHeight)
}
Hd_CameraModule_HIK_soft* create()
Hd_CameraModule_HIK_hard_USB* create()
{
qDebug() << "[INFO] " << "Hd_CameraModule_HIK_soft create success!" ;
return new Hd_CameraModule_HIK_soft;
qDebug() << "[INFO] " << "Hd_CameraModule_HIK_hard_USB create success!" ;
return new Hd_CameraModule_HIK_hard_USB;
}
void destory(Hd_CameraModule_HIK_soft * ptr)
void destory(Hd_CameraModule_HIK_hard_USB * ptr)
{
if(ptr)
{
delete ptr;
ptr = nullptr;
}
qDebug() << "[INFO] " << "Hd_CameraModule_HIK_soft destory success!";
qDebug() << "[INFO] " << "Hd_CameraModule_HIK_hard_USB destory success!";
}
//回调函数;
//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题
@@ -339,7 +350,7 @@ void SetGain(float GainValue)
MV_CC_SetEnumValue(handle, "GainAuto", 0);
MV_CC_SetFloatValue(handle, "Gain", GainValue);
}
Hd_CameraModule_HIK_soft::Hd_CameraModule_HIK_soft()
Hd_CameraModule_HIK_hard_USB::Hd_CameraModule_HIK_hard_USB()
{
n_mutex = new QMutex();
m_thread = new MyThread;
@@ -353,7 +364,7 @@ void CloseDevice()
handle = nullptr; //此处注释掉的话,软件断开再连接,回调函数不出图
}
Hd_CameraModule_HIK_soft::~Hd_CameraModule_HIK_soft()
Hd_CameraModule_HIK_hard_USB::~Hd_CameraModule_HIK_hard_USB()
{
m_flag = true;
Sleep(10);
@@ -374,7 +385,7 @@ Hd_CameraModule_HIK_soft::~Hd_CameraModule_HIK_soft()
qDebug() << "[INFO] " << " delete success!";
}
//从类中读数据到实例对象
bool Hd_CameraModule_HIK_soft::readData(std::vector<cv::Mat> &mat,QByteArray &data)
bool Hd_CameraModule_HIK_hard_USB::readData(std::vector<cv::Mat> &mat,QByteArray &data)
{
if (queuepic.isEmpty())
{
@@ -392,9 +403,16 @@ bool Hd_CameraModule_HIK_soft::readData(std::vector<cv::Mat> &mat,QByteArray &da
return true;
}
//实例对象把数据写入到类
bool Hd_CameraModule_HIK_soft::writeData(std::vector<cv::Mat> &mat,QByteArray &data)
bool Hd_CameraModule_HIK_hard_USB::writeData(std::vector<cv::Mat> &mat,QByteArray &data)
{
//2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值
if (data.contains("deviceList")) {
auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10));
if (result.nDeviceNum != 0) {
m_stDevList = result;
return true;
}
}
if (data == "rest_newProductIn")
{
//根据实际项目,设置初始值:曝光、增益,ROI区域等
@@ -476,7 +494,7 @@ bool Hd_CameraModule_HIK_soft::writeData(std::vector<cv::Mat> &mat,QByteArray &d
data.append("TriggerMode_" + ui.comboBox_triggerMode->currentText());*/
qDebug() << "Hd_CameraModule_HIK_soft::writeData::" << data;
qDebug() << "Hd_CameraModule_HIK_hard_USB::writeData::" << data;
m_flag = false;
//Username = data.toStdString();
@@ -485,7 +503,7 @@ bool Hd_CameraModule_HIK_soft::writeData(std::vector<cv::Mat> &mat,QByteArray &d
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
bool Hd_CameraModule_HIK_soft::initParas(QByteArray& initData)
bool Hd_CameraModule_HIK_hard_USB::initParas(QByteArray& initData)
{
QByteArrayList valueList = initData.split('+');
Username = valueList[0];
@@ -497,7 +515,7 @@ bool Hd_CameraModule_HIK_soft::initParas(QByteArray& initData)
bool ifOk = true;
if (handle == NULL)
ifOk = connctDevice();
ifOk = connectDevice();
if (ifOk == false)
return false;
if (valueList.size() > 1)
@@ -618,7 +636,7 @@ bool Hd_CameraModule_HIK_soft::initParas(QByteArray& initData)
return ifOk;
}
bool Hd_CameraModule_HIK_soft::run()
bool Hd_CameraModule_HIK_hard_USB::run()
{
if (imgIndex == expourseTimeList.size())
imgIndex = 0;
@@ -709,7 +727,7 @@ bool Hd_CameraModule_HIK_soft::run()
}
//相机连接状态:正常连接或断开
bool Hd_CameraModule_HIK_soft::checkStatus()
bool Hd_CameraModule_HIK_hard_USB::checkStatus()
{
//status = moduleStatus;
return moduleStatus;
@@ -1,5 +1,5 @@
#ifndef Hd_CameraModule_HIK_soft_H
#define Hd_CameraModule_HIK_soft_H
#ifndef Hd_CameraModule_HIK_hard_USB_H
#define Hd_CameraModule_HIK_hard_USB_H
#include <QtCore/qglobal.h>
@@ -22,11 +22,11 @@ using namespace cv;
class MyThread;
class Hd_CameraModule_HIK_soft :public dsModuleBase
class Hd_CameraModule_HIK_hard_USB :public dsModuleBase
{
public:
Hd_CameraModule_HIK_soft();
virtual ~Hd_CameraModule_HIK_soft();
Hd_CameraModule_HIK_hard_USB();
virtual ~Hd_CameraModule_HIK_hard_USB();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>& mat, QByteArray& data);
//实例对象把数据写入到类
@@ -52,8 +52,8 @@ signals:
extern "C"
{
Q_DECL_EXPORT Hd_CameraModule_HIK_soft * create();
Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_soft * ptr);
Q_DECL_EXPORT Hd_CameraModule_HIK_hard_USB * create();
Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_USB * ptr);
}
#endif // Hd_CameraModule_HIK_soft_H
#endif // Hd_CameraModule_HIK_hard_USB_H
@@ -25,6 +25,16 @@ bool ifRunning = false;
MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表
//MV_GENTL_IF_INFO_LIST m_stIFList;
void CloseDevice();
static MV_CC_DEVICE_INFO_LIST QByteArrayToMV_CC_DeviceInfoList(const QByteArray& byteArray) {
MV_CC_DEVICE_INFO_LIST deviceInfoList;
if (byteArray.size() == sizeof(MV_CC_DEVICE_INFO_LIST)) {
memcpy(&deviceInfoList, byteArray.constData(), sizeof(MV_CC_DEVICE_INFO_LIST));
}
else {
qDebug() << "Invalid size of QByteArray for MV_CC_DEVICE_INFO_LIST!";
}
return deviceInfoList;
}
QString byteArrayToUnicode(const QByteArray array) {
// state用于保存转换状态,它的成员invalidChars,可用来判断是否转换成功
@@ -93,9 +103,15 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra
//搜索所有设备
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);
if (m_stDevList.nDeviceNum == 0) {
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);
if (MV_OK != nRet)
{
return 0;
}
}
for (int i = 0; i < m_stDevList.nDeviceNum; i++)
{
//SN
@@ -109,10 +125,6 @@ int SearchDevice()
break;
}
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
@@ -246,13 +258,13 @@ void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) {
}
Hd_CameraModule_HIK_hard_PCIE* create()
Hd_CameraModule_HIK_soft_GIGE* create()
{
qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!";
return new Hd_CameraModule_HIK_hard_PCIE;
return new Hd_CameraModule_HIK_soft_GIGE;
}
void destory(Hd_CameraModule_HIK_hard_PCIE* ptr)
void destory(Hd_CameraModule_HIK_soft_GIGE* ptr)
{
if (ptr)
{
@@ -348,12 +360,12 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra
<< "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgCnt << "nFrameNum : " << frameNum;
}
Hd_CameraModule_HIK_hard_PCIE::Hd_CameraModule_HIK_hard_PCIE()
Hd_CameraModule_HIK_soft_GIGE::Hd_CameraModule_HIK_soft_GIGE()
{
//m_thread = new MyThread;
//m_mutex = new QMutex();
}
Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE()
Hd_CameraModule_HIK_soft_GIGE::~Hd_CameraModule_HIK_soft_GIGE()
{
CloseDevice();
if (n_mutex)
@@ -365,7 +377,7 @@ Hd_CameraModule_HIK_hard_PCIE::~Hd_CameraModule_HIK_hard_PCIE()
qDebug() << "[INFO] " << " delete success!";
}
//从类中读数据到实例对象
bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector<cv::Mat>& mat, QByteArray& data)
bool Hd_CameraModule_HIK_soft_GIGE::readData(std::vector<cv::Mat>& mat, QByteArray& data)
{
if (queuepic.isEmpty())
{
@@ -382,9 +394,16 @@ bool Hd_CameraModule_HIK_hard_PCIE::readData(std::vector<cv::Mat>& mat, QByteArr
}
//实例对象把数据写入到类;加载模型后会运行此函数
bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector<cv::Mat>& mat, QByteArray& data)
bool Hd_CameraModule_HIK_soft_GIGE::writeData(std::vector<cv::Mat>& mat, QByteArray& data)
{
Q_UNUSED(mat);
if (data.contains("deviceList")) {
auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10));
if (result.nDeviceNum != 0) {
m_stDevList = result;
return true;
}
}
QStringList dataList = QString::fromUtf8(data).split("_");
//2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值
if (data == "rest_newProductIn")
@@ -430,7 +449,7 @@ bool Hd_CameraModule_HIK_hard_PCIE::writeData(std::vector<cv::Mat>& mat, QByteAr
return true;
}
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
bool Hd_CameraModule_HIK_hard_PCIE::initParas(QByteArray& initData)
bool Hd_CameraModule_HIK_soft_GIGE::initParas(QByteArray& initData)
{
QByteArrayList valueList = initData.split('+');
Username = valueList[0];
@@ -512,7 +531,7 @@ bool Hd_CameraModule_HIK_hard_PCIE::initParas(QByteArray& initData)
return ifOk;
}
bool Hd_CameraModule_HIK_hard_PCIE::run()
bool Hd_CameraModule_HIK_soft_GIGE::run()
{
//queuepic.clear();
qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username);
@@ -571,7 +590,7 @@ bool Hd_CameraModule_HIK_hard_PCIE::run()
}
//相机连接状态:正常连接或断开
bool Hd_CameraModule_HIK_hard_PCIE::checkStatus()
bool Hd_CameraModule_HIK_soft_GIGE::checkStatus()
{
//status = moduleStatus;
return moduleStatus;
@@ -1,5 +1,5 @@
#ifndef Hd_CameraModule_HIK_hard_PCIE_H
#define Hd_CameraModule_HIK_hard_PCIE_H
#ifndef Hd_CameraModule_HIK_soft_GIGE_H
#define Hd_CameraModule_HIK_soft_GIGE_H
#include <QtCore/qglobal.h>
#include <MvCameraControl.h>
#include <CameraParams.h>
@@ -14,11 +14,11 @@
using namespace cv;
#pragma execution_character_set("utf-8")
class Hd_CameraModule_HIK_hard_PCIE :public dsModuleBase
class Hd_CameraModule_HIK_soft_GIGE :public dsModuleBase
{
public:
Hd_CameraModule_HIK_hard_PCIE();
virtual ~Hd_CameraModule_HIK_hard_PCIE();
Hd_CameraModule_HIK_soft_GIGE();
virtual ~Hd_CameraModule_HIK_soft_GIGE();
//从类中读数据到实例对象
bool readData(std::vector<cv::Mat>& mat, QByteArray& data);
//实例对象把数据写入到类
@@ -35,9 +35,9 @@ private:
extern "C"
{
Q_DECL_EXPORT Hd_CameraModule_HIK_hard_PCIE * create();
Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_hard_PCIE * ptr);
Q_DECL_EXPORT Hd_CameraModule_HIK_soft_GIGE * create();
Q_DECL_EXPORT void destory(Hd_CameraModule_HIK_soft_GIGE * ptr);
}
#endif // Hd_CameraModule_HIK_hard_H
//Hd_CameraModule_HIK_hard_PCIE
//Hd_CameraModule_HIK_soft_GIGE