Files
ds-628/BaseModules/Hd_CameraModule_HIK3_2/Hd_CameraModule_HIK3_2.cpp
T
2024-09-27 14:31:22 +08:00

865 lines
31 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Hd_CameraModule_HIK3_2.h"
#include <QThread>
#include <QQueue>
#include <QMutex>
#include <QTextCodec>
#include <QCoreApplication>
#include <QDebug>
#include <QRandomGenerator>
QByteArray mv_Status = "connected";//0106 新增相机断联报警
//cv::Mat srcImage;
int index = -1; //相机序号
void* handle; //相机指针
string Username = "";
bool m_flag = false;
MV_CC_DEVICE_INFO_LIST m_stDevList;//相机设备
cv::Mat srcImage;
bool moduleStatus = true;
//data == "rest_newProductIn"时要结束run;机台报警,取图超时,复位后重新拍的情况。
bool ifBreak = false;
//ifRunning减少ifBreak的判断;"rest_newProductIn"时,Logic_camera_thread框架会结束未处理完的相相机取图
bool ifRunning = false;
bool ifChangeExpourseAndGain = true;
MV_CAM_TRIGGER_SOURCE initTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
MV_CAM_TRIGGER_SOURCE currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
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;
}
#pragma execution_character_set("utf-8")
QMutex* n_mutex;// = new QMutex();
//是否为标准通信流程:
//标准通信流程,run函数设置曝光/增益;非标准通信流程(简单通信流程),回调函数设置曝光/增益
bool ifStandard = false;
//相机取图超时时间
int getImageTimeOut = 1000;
//总取图数
int imgIndex = 0;
//曝光值列表
QQueue<float> expourseTimeList;
//增益列表
QQueue<float> gainList;
//0106 断线重连
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser);
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0);
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;
}
}
//搜索所有设备
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++)
{
//SN
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);
if (Username == userName)
{
index = i;
break;
}
}
if (MV_OK != nRet)
{
return 0;
}
return -1;
}
bool connctDevice()
{
index = -1;
SearchDevice();
if (index == -1)
{
//未匹配到相机
//qDebug() << "[Waring] " << "Hd_CameraModule_HIK3_2 not match --CameraName:" << QString::fromStdString(Username);
return false;
}
unsigned char* name = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.chUserDefinedName;
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);
handle = NULL; //此处注释掉的话,软件断开再连接,回调函数不出图
return false;
}
//打开相机
int nRet=MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]);
if (MV_OK != nRet)
{
//qDebug() << "Set MV_CC_CreateHandle fail! nRet " << nRet;
return false;
}
//自动IP功能:注意,只获取GIGE、USB相机,其它相机不可和HIK相机在同网段。
// ch:判断设备IP是否可达
bool bAccessible=true;// = MV_CC_IsDeviceAccessible(m_stDevList.pDeviceInfo[index], MV_ACCESS_Exclusive);
if (m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nNetExport / 256 !=
m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nCurrentIp / 256)//nCurrentIp相机IP;nNetExport网口IP;判断前3位
bAccessible = false;
if (!bAccessible)
{
unsigned int m_dwIpaddress = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nNetExport; //nCurrentIp相机IP;nNetExport网口IP
unsigned int m_dwNetworkMask = m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nCurrentSubNetMask;//掩码
unsigned int m_dwDefaultGateway = m_dwIpaddress - m_dwIpaddress % 256 + 254;//默认网关是254
for (int i = 2; i < 253; i++)//自动IP
{
unsigned int auto_dwIpaddress = m_dwIpaddress - m_dwIpaddress % 256 + i;
bool ifHas = false;
for (int k = 0; k < m_stDevList.nDeviceNum; k++)
{
unsigned int m_nNetExport = m_stDevList.pDeviceInfo[k]->SpecialInfo.stGigEInfo.nNetExport;
unsigned int m_nCurrentIp = m_stDevList.pDeviceInfo[k]->SpecialInfo.stGigEInfo.nCurrentIp;
//qDebug() << "k:" << k << " nNetExport:" << m_nNetExport << " nCurrentIp::" << m_nCurrentIp;
if (auto_dwIpaddress == m_nNetExport
|| auto_dwIpaddress == m_nCurrentIp) //IP占用判断
{
ifHas = true;
break;
}
}
if (ifHas)
continue;
nRet = MV_GIGE_ForceIpEx(handle, auto_dwIpaddress, m_dwNetworkMask, m_dwDefaultGateway);
if (MV_OK == nRet)
break;
else
{
MV_CC_DestroyHandle(handle);
handle = NULL;
nRet = MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]);
if (MV_OK != nRet)
{
qDebug() << "Set MV_GIGE_ForceIpEx fail! nRet " << nRet;
return false;
}
}
}
if (MV_OK != nRet)
{
//ShowErrorMsg(TEXT("ForceIp fail"), nRet);
qDebug() << "Set ForceIp fail! nRet " << nRet;
MV_CC_DestroyHandle(handle);
handle = NULL;
return false;
}
MV_CC_DestroyHandle(handle);
handle = NULL;
//ch:需要重新创建句柄,设置为静态IP方式进行保存
m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nCurrentIp = m_dwIpaddress;
m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nCurrentSubNetMask = m_dwNetworkMask;
m_stDevList.pDeviceInfo[index]->SpecialInfo.stGigEInfo.nDefultGateWay = m_dwDefaultGateway;
/*qDebug()<<"m_dwIpaddress "<< QString::number(m_dwIpaddress / (256 * 256 * 256)) + "." + QString::number(m_dwIpaddress / (256 * 256) % 256) + "."
+ QString::number(m_dwIpaddress / 256 % 256) + "." + QString::number(m_dwIpaddress % 256);
qDebug() << "m_dwNetworkMask " << QString::number(m_dwNetworkMask / (256 * 256 * 256)) + "." + QString::number(m_dwNetworkMask / (256 * 256) % 256) + "."
+ QString::number(m_dwNetworkMask / 256 % 256) + "." + QString::number(m_dwNetworkMask % 256);
qDebug() << "m_dwDefaultGateway " << QString::number(m_dwDefaultGateway / (256 * 256 * 256)) + "." + QString::number(m_dwDefaultGateway / (256 * 256) % 256) + "."
+ QString::number(m_dwDefaultGateway / 256 % 256) + "." + QString::number(m_dwDefaultGateway % 256);*/
nRet = MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[index]);
if (MV_OK != nRet)
{
qDebug() << "MV_CC_CreateHandle fail! nRet " << nRet;
//ShowErrorMsg(TEXT("Create handle fail"), nRet);
return false;
}
nRet = MV_GIGE_SetIpConfig(handle, MV_IP_CFG_STATIC);
if (MV_OK != nRet)//这里会失败,再试一次。
{
qDebug() << "MV_GIGE_SetIpConfig fail! nRet " << nRet;
//ShowErrorMsg(TEXT("Set Ip config fail"), nRet);
MV_CC_DestroyHandle(handle);
handle = NULL;
return false;
}
}
nRet = MV_CC_OpenDevice(handle);
////触发模式
if (currentTriggerSource != MV_TRIGGER_SOURCE_SOFTWARE)
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
else
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
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;
return false;
}
// 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, handle);//断线重连
if (MV_OK != nRet)
return false;
MV_CC_StartGrabbing(handle);
return true;
}
//0106 断线重连
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser)
{
mv_Status = "disconnect";
qDebug() << "[Error] " << " MV camera disconnects!";
moduleStatus = false;
if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT)
{
//断开连接
MV_CC_CloseDevice(handle);
int nRet = MV_CC_DestroyHandle(handle);
handle = NULL;
BOOL bConnected = FALSE;
// 初始化随机数生成器
//QRandomGenerator::seed();
while (1)
{
// 生成一个随机整数
int randomNumber = QRandomGenerator::global()->bounded(500); //多相机无随机时,重连稍慢
Sleep(randomNumber);
// 输出到控制台
//qDebug() << "Random Number:" << randomNumber;
Sleep(100);
if (connctDevice() == true)
{
qWarning() << "[Hd_CameraModule_HIK3_2] " << " Hd_CameraModule_HIK3_2 create success again! ";
moduleStatus = true;
break;
}
}
}
}
void _stdcall ExceptionCB(unsigned int nMesgType, void* pUser) {
mv_Status = "disconnect";
qDebug() << "[Error] " << " MV camera disconnects!";
moduleStatus = false;
}
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_CameraModule_HIK3_2* create()
{
qDebug() << "[INFO] " << "Hd_CameraModule_HIK3_2 create success!" ;
return new Hd_CameraModule_HIK3_2;
}
void destory(Hd_CameraModule_HIK3_2 * ptr)
{
if(ptr)
{
delete ptr;
ptr = nullptr;
}
qDebug() << "[INFO] " << "Hd_CameraModule_HIK3_2 destory success!";
}
//回调函数;
//经测试,相机像素格式Mono8、RGB8是可以正常转换的,YUV422还需要优化;RGB8格式比YUV422帧率低;BGR格式会导致异色问题
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0)
{
n_mutex->lock();
double time_Start = (double)clock();
int frameNum = 0;
srcImage = cv::Mat();
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);
}
////获取的是RGB8图
//else if (pFrameInfo0->enPixelType == PixelType_Gvsp_RGB8_Packed)
//{
// cv::Mat dst = cv::Mat(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3, pData0);
// //cv::cvtColor(matimage, matimage, cv::COLOR_RGB2BGR);
// srcImage = cv::Mat::zeros(pFrameInfo0->nHeight, pFrameInfo0->nWidth, CV_8UC3);
// std::vector<cv::Mat> channels;
// cv::split(dst, channels);//分割matimage的通道
// std::vector<cv::Mat> dstchannels;
// for (int i = 2; i >= 0; i--)
// {
// dstchannels.push_back(channels[i]);
// }
// merge(dstchannels, srcImage);
//}
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);
}
//cv::Mat resizeM;
//cv::resize(srcImage, resizeM, cv::Size(), 0.1, 0.1);
//cv::imwrite("../runtime/Bin_DEVICE/testImg/"+Username + ".png", resizeM);
m_flag = true;
n_mutex->unlock();
pData0 = { 0 };
double time_End = (double)clock();
QString tmpDate = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
qDebug() << tmpDate << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms"
<< "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum;
/*QString savePath = "../runtime/Bin_DEVICE/testImg/camera_"+QString::fromStdString(Username) +"_" + QString::number(imgIndex + 1) + ".png";
cv::Mat resizeS;
cv::resize(srcImage, resizeS, cv::Size(), 0.1, 0.1);
cv::imwrite(savePath.toStdString(), resizeS);*/
}
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);
}
Hd_CameraModule_HIK3_2::Hd_CameraModule_HIK3_2()
{
n_mutex = new QMutex();
m_thread = new MyThread;
ifRunning = true;
QFuture<void> myF= QtConcurrent::run(this, &Hd_CameraModule_HIK3_2::threadCheckCallBack);
}
//关闭设备
void CloseDevice()
{
MV_CC_StopGrabbing(handle);
MV_CC_CloseDevice(handle);
MV_CC_DestroyHandle(handle);
handle = NULL; //此处注释掉的话,软件断开再连接,回调函数不出图
}
Hd_CameraModule_HIK3_2::~Hd_CameraModule_HIK3_2()
{
ifRunning = false;
m_flag = false;
Sleep(10);
CloseDevice();
if (n_mutex)
{
delete n_mutex;
n_mutex = nullptr;
}
if(m_thread)
{
m_thread->exit();
m_thread->wait(1);
delete m_thread;
m_thread = nullptr;
}
qDebug() << "[INFO] " << " delete success!";
}
void Hd_CameraModule_HIK3_2::threadCheckCallBack()
{
bool ifThemoduleStatus = true;
while (ifRunning)
{
//if (currentTriggerSource != MV_TRIGGER_SOURCE_SOFTWARE)
if (m_flag == true)
{
qDebug() << "[INFO] " << "emit trigged:" ;
emit trigged(true);
n_mutex->lock();
m_flag = false;
n_mutex->unlock();
}
if (ifThemoduleStatus != moduleStatus)
{
qDebug() << "[INFO] " << "moduleStatus changed emit trigged:" << moduleStatus;
emit trigged(moduleStatus);
ifThemoduleStatus = moduleStatus;
}
if(moduleStatus==false)
qApp->processEvents();
Sleep(5);
}
}
//从类中读数据到实例对象
bool Hd_CameraModule_HIK3_2::readData(std::vector<cv::Mat> &mat,QByteArray &data)
{
if (!srcImage.data)
{
qCritical() << __FUNCTION__ << " line:" <<__LINE__ << " srcImage is null";
return false;
}
n_mutex->lock();
mat.push_back(srcImage.clone());
srcImage = cv::Mat();
n_mutex->unlock();
QString qimgIndex = "imgIndex_" + QString::number(imgIndex-1)+"_中文测试";
data = qimgIndex.toLocal8Bit();
QString tmpDate = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
qDebug() << tmpDate << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex-1;
return true;
}
//实例对象把数据写入到类
bool Hd_CameraModule_HIK3_2::writeData(std::vector<cv::Mat> &mat,QByteArray &data)
{
//2024.02.18更新,相机对应的读SN信号时,表示新产品进入,设置初始值
if (data == "rest_newProductIn")
{
//根据实际项目,设置初始值:曝光、增益,ROI区域等
{
if (expourseTimeList.size() > 0)
SetExposureTime(expourseTimeList[0]);
if (gainList.size() > 0)
SetGain(gainList[0]);
}
n_mutex->lock();
srcImage = cv::Mat();
n_mutex->unlock();
if (ifRunning == true)
{
ifBreak = true;
Sleep(10);
}
imgIndex = 0;
return true;
}
//else
//{
// //m_flag = false;
// //expourseTimeList.clear();
// //gainList.clear();
//}
if (data == "ifChangeExpourseAndGain_false")
ifChangeExpourseAndGain = false;
else
ifChangeExpourseAndGain = true;
if (data.contains("SetExposureTime_"))
{
QByteArrayList dataList = data.split('#');
for (int i = 0; i < dataList.size(); i++)
{
if (dataList[i].contains("SetExposureTime_"))
{
int value = byteArrayToUnicode(dataList[i]).split("SetExposureTime_")[1].toInt();
SetExposureTime(value);
}
if (dataList[i].contains("SetGain_"))
{
double value = byteArrayToUnicode(dataList[i]).split("SetGain_")[1].toInt();
SetGain(value);
}
if (dataList[i].contains("TriggerMode_"))
{
QString value = byteArrayToUnicode(dataList[i]).split("TriggerMode_")[1];
if (value == "软触发")
////触发模式
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
}
else
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
currentTriggerSource = MV_TRIGGER_SOURCE_LINE0;
}
}
}
}
//调试模式下,data==ifChangeExpourseAndGain_false;非调试模式运行时,data不包含SetExposureTime_
else if (data != "ifChangeExpourseAndGain_false" && initTriggerSource != currentTriggerSource)
{
MV_CC_SetEnumValue(handle, "TriggerSource", initTriggerSource);
currentTriggerSource = initTriggerSource;
}
/*data.append("SetExposureTime_" + ui.spinBox->text() + "#");
data.append("SetGain_" + ui.doubleSpinBox->text() + "#");
data.append("TriggerMode_" + ui.comboBox_triggerMode->currentText());*/
qDebug() << "Hd_CameraModule_HIK3_2::writeData::" << data;
//m_flag = false;
//Username = data.toStdString();
return true;
}
//传入initParas函数,格式为:相机key+参数名1#参数值1#参数值2+参数名2#参数值1...
bool Hd_CameraModule_HIK3_2::initParas(QByteArray& initData)
{
QByteArrayList valueList = initData.split('+');
Username = valueList[0];
imgIndex = 0;
expourseTimeList.clear();
gainList.clear();
bool ifOk = true;
if (handle == NULL)
ifOk = connctDevice();
if (ifOk == false)
{
qDebug() << "try connctDevice again!"<<QString::fromStdString(Username);
ifOk = connctDevice();
}
if (ifOk == false)
return false;
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());
}
if (valuei.contains("触发方式"))
{
QStringList valueL = valuei.split('#');
if (valueL.size() > 1)
if (valueL[1].toInt() >= 0)
if (valueL[1] == "软触发")
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);
currentTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
initTriggerSource = MV_TRIGGER_SOURCE_SOFTWARE;
}
else
{
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
currentTriggerSource = MV_TRIGGER_SOURCE_LINE0;
initTriggerSource = MV_TRIGGER_SOURCE_LINE0;
}
}
}
if (ifOk == true)
{
if (expourseTimeList.size() > 0)
SetExposureTime(expourseTimeList[0]);
if (gainList.size() > 0)
SetGain(gainList[0]);
}
imgIndex = 0;
if (ifOk == true)
{
MVCC_FLOATVALUE mf = { 0 };
MV_CC_GetFloatValue(handle, "ExposureTime", &mf);
std::cout << "ExposureTime::" << mf.fCurValue << std::endl;
mf = { 0 };
MV_CC_GetFloatValue(handle, "Gain", &mf);
std::cout << "Gain::" << mf.fCurValue << std::endl;
MVCC_INTVALUE mI = { 0 };
MV_CC_GetIntValue(handle, "OffsetX", &mI);
std::cout << "OffsetX::" << mI.nCurValue << std::endl;
mI = { 0 };
MV_CC_GetIntValue(handle, "OffsetY", &mI);
std::cout << "OffsetY::" << mI.nCurValue << std::endl;
mI = { 0 };
MV_CC_GetIntValue(handle, "Width", &mI);
std::cout << "Width::" << mI.nCurValue << std::endl;
mI = { 0 };
MV_CC_GetIntValue(handle, "Height", &mI);
std::cout << "Height::" << mI.nCurValue << std::endl;
MVCC_ENUMVALUE me = { 0 };
MV_CC_GetEnumValue(handle,"BalanceWhiteAuto",&me); //自动白平衡
std::cout << "BalanceWhiteAuto::" << me.nCurValue << std::endl;
}
return ifOk;
}
bool Hd_CameraModule_HIK3_2::run()
{
if (moduleStatus == false)
return false;
if (imgIndex == expourseTimeList.size())
imgIndex = 0;
//Sleep(100);
QString tmpDate = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz");
qDebug() << tmpDate << "[INFO] " << " run start" <<QString::fromStdString(Username);
bool result = false;
ifRunning = true;
ifBreak = false;
//srcImage.release();
try
{
//n_mutex->lock();
m_flag = false;
//Sleep(2);
//n_mutex->unlock();
//m_thread->run(); //start()线程运行,频率高时有低概率无响应;
if (currentTriggerSource == MV_TRIGGER_SOURCE_SOFTWARE)
{
MV_CC_SetCommandValue(handle, "TriggerSoftware");
qDebug() << "[INFO] " << "TriggerSoftware";
}
else
qDebug() << "[INFO] " << "TriggerHardware";
//MV_CC_SetCommandValue(handle, "TriggerSoftware");
//Sleep(15);
int mytime = 0;
qDebug() << "[INFO] " << " waite Img" << QString::fromStdString(Username);
while (true)
{
if (moduleStatus == false || mytime++ > getImageTimeOut || ifBreak == true )//|| m_flag==true)
{
result = false;
break;
}
n_mutex->lock();
if (m_flag == true)
{
n_mutex->unlock();
result = true;
break;
}
n_mutex->unlock();
Sleep(1);
}
Sleep(1);
//qDebug() << "[INFO] " << " expourseTimeList " << QString::fromStdString(Username);
//软触发,不考虑误触发、漏触发
if (ifChangeExpourseAndGain == true)
{
imgIndex++;
if (expourseTimeList.size() > 1 && expourseTimeList[imgIndex % expourseTimeList.size()] != expourseTimeList[(imgIndex - 1) % expourseTimeList.size()])
SetExposureTime(expourseTimeList[imgIndex % expourseTimeList.size()]);
//Sleep(1);
if (gainList.size() > 1 && gainList[imgIndex % gainList.size()] != gainList[(imgIndex - 1) % gainList.size()])
SetGain(gainList[imgIndex % gainList.size()]);
//Sleep(1);
}
/*if (result == false)
{
QString currPath = "../runtime/Bin_DEVICE/testImg/testImg_";
if (ifChangeExpourseAndGain == true)
currPath +=QString::number(imgIndex-1);
else
currPath += QString::number(imgIndex);
currPath += ".jpg";
n_mutex->lock();
srcImage = cv::imread(currPath.toStdString());
n_mutex->unlock();
qDebug() << "取图失败,读取图片:" << currPath;
result = true;
}*/
}
catch (QString ev)
{
qDebug() << "[Error] " << " ev:" << ev ;
}
qDebug() << "[INFO] " << __LINE__ << " run end" ;
return result;
}
//相机连接状态:正常连接或断开
bool Hd_CameraModule_HIK3_2::checkStatus()
{
//status = moduleStatus;
return moduleStatus;
}
void MyThread::run()
{
MV_CC_SetCommandValue(handle, "TriggerSoftware");
}