Files
952-11/BaseModules/Hd_MvCamera_module_Hard/hd_mvcamera_module.cpp
T
2024-11-02 01:15:48 +08:00

399 lines
13 KiB
C++

#include "hd_mvcamera_module.h"
#include <QByteArray>
#include <QDebug>
#include <qqueue.h>
QQueue<cv::Mat>imgQueue;
std::mutex imgQueueMutex;//掉线锁
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<string>((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_LINE0);
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!";
}
/// <summary>
/// 回调取图
/// </summary>
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);
imgQueueMutex.lock();
imgQueue.append(srcImage);
imgQueueMutex.unlock();
//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()
{
int nRet=MV_OK;
if (m_stDevList.nDeviceNum == 0)
{
memset(&m_stDevList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
// ch:枚举子网内所有设备 | en:Enumerate all devices within subnet
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.chUserDefinedName;
string serialNumber = static_cast<string>((LPCSTR)name);
if (Username == serialNumber)
{
index = i;
break;
}
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
#include <QByteArray>
#include <QtGlobal>
QByteArray MV_CC_DeviceInfoListToQByteArray(const MV_CC_DEVICE_INFO_LIST& deviceInfoList) {
QByteArray byteArray;
byteArray.resize(sizeof(MV_CC_DEVICE_INFO_LIST));
memcpy(byteArray.data(), &deviceInfoList, sizeof(MV_CC_DEVICE_INFO_LIST));
return byteArray;
}
// 将 QByteArray 转换为 MV_CC_DEVICE_INFO_LIST
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;
}
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<cv::Mat>& mat, QByteArray& data)
{
QString inputString = QString::fromUtf8(data);
if (data == "connect")
{
data = mv_Status;
return true;
}
if (data == "m_stDevList")
{
data = MV_CC_DeviceInfoListToQByteArray(m_stDevList);
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
{
int cnt = 0;
while (imgQueue.size()==0)
{
cnt++;
QThread::msleep(1);
if (cnt > 200)
{
cv::Mat blank_image(100, 100, CV_8UC1, cv::Scalar(0, 0, 0));
mat.push_back(blank_image);
return true;
}
}
imgQueueMutex.lock();
mat.push_back(imgQueue.dequeue());
imgQueueMutex.unlock();
//imgQueue.clear();
}
return true;
}
bool Hd_MvCamera_module::reciveData(std::vector<cv::Mat>& mat, QByteArray& data)
{
m_flag = false;
if (data.size() > 1000)
m_stDevList = QByteArrayToMV_CC_DeviceInfoList(data);
else
Username = data.toStdString();
return true;
}
bool Hd_MvCamera_module::initParas(QByteArray&)
{
return true;
if (!Username.compare("dummy"))
{
qDebug() << "[INFO] " << " start" << "--UserName: dummy creat sucess";
return true;
}
SearchDevice();
if (m_stDevList.nDeviceNum == 0)
return false;
unsigned char* defineName = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName;
string userName = static_cast<string>((LPCSTR)defineName);
//QByteArray abc = MV_CC_DeviceInfoListToQByteArray(m_stDevList);
//MV_CC_DEVICE_INFO_LIST ttt;
//ttt = QByteArrayToMV_CC_DeviceInfoList(abc);
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;
int cnt = 0;
while (true)
{
if(reconnectCount!= reconnectSign)
m_thread->start();
if (m_flag || cnt>200)
{
break;
}
cnt++;
QThread::msleep(1);
}
m_flag = false;
}
catch (QString ev)
{
qDebug() << "[Error] " << " ev:" << ev;
}
qDebug() << "[INFO] " << __LINE__ << " run end";
return true;
}
void MyThread::run()
{
//imgQueue.clear();
// MV_CC_SetCommandValue(handle, "TriggerSoftware");
}