|
|
|
@@ -1,4 +1,5 @@
|
|
|
|
|
#include "Hd_CameraModule_HIK_General.h"
|
|
|
|
|
#include "Hd_CameraModule_HIK_General.h"
|
|
|
|
|
#include <HikDevicelistCache.h>
|
|
|
|
|
#include <qelapsedtimer.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
#include <QTextCodec>
|
|
|
|
@@ -25,7 +26,6 @@ int getImageTimeOut = 3000;
|
|
|
|
|
bool runFlag = true;
|
|
|
|
|
//总取图数
|
|
|
|
|
int imgIndex = 0;
|
|
|
|
|
MV_CC_DEVICE_INFO_LIST m_stDevList; // ch:设备信息列表结构体变量,用来存储设备列表
|
|
|
|
|
string Username = "";
|
|
|
|
|
int cameraIndex = -1;
|
|
|
|
|
QString lastError;
|
|
|
|
@@ -73,20 +73,11 @@ void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser);
|
|
|
|
|
void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFrameInfo0, void* pUser0);
|
|
|
|
|
//搜索所有设备
|
|
|
|
|
int SearchDevice(){
|
|
|
|
|
|
|
|
|
|
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 -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < m_stDevList.nDeviceNum; i++)
|
|
|
|
|
const auto deviceInfoList = appHikDeviceListCache().getDeviceInfoList();
|
|
|
|
|
for (int i = 0; i < deviceInfoList.nDeviceNum; i++)
|
|
|
|
|
{
|
|
|
|
|
//SN
|
|
|
|
|
unsigned char* name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber;
|
|
|
|
|
unsigned char* name = deviceInfoList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chSerialNumber;
|
|
|
|
|
string userName = static_cast<string>((LPCSTR)name);
|
|
|
|
|
if (Username == userName)
|
|
|
|
|
{
|
|
|
|
@@ -94,7 +85,7 @@ int SearchDevice(){
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name = m_stDevList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber;
|
|
|
|
|
name = deviceInfoList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chSerialNumber;
|
|
|
|
|
userName = static_cast<string>((LPCSTR)name);
|
|
|
|
|
if (Username == userName)
|
|
|
|
|
{
|
|
|
|
@@ -110,11 +101,11 @@ bool connectDevice()
|
|
|
|
|
int cameraIndex = SearchDevice();
|
|
|
|
|
if (cameraIndex == -1){
|
|
|
|
|
//未匹配到相机
|
|
|
|
|
qDebug() << "[Waring] " << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username);
|
|
|
|
|
qDebug() << "Hd_CameraModule_HIK not match --CameraName:" << QString::fromStdString(Username);
|
|
|
|
|
lastError = "找不到相机" + QString::fromStdString(Username);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(handleMutex);
|
|
|
|
|
if (handle != NULL)
|
|
|
|
|
{
|
|
|
|
@@ -125,7 +116,8 @@ bool connectDevice()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//打开相机
|
|
|
|
|
MV_CC_CreateHandle(&handle, m_stDevList.pDeviceInfo[cameraIndex]);
|
|
|
|
|
const auto deviceInfoList = appHikDeviceListCache().getDeviceInfoList();
|
|
|
|
|
MV_CC_CreateHandle(&handle, deviceInfoList.pDeviceInfo[cameraIndex]);
|
|
|
|
|
int nRet = MV_CC_OpenDevice(handle);
|
|
|
|
|
////触发模式
|
|
|
|
|
if(triggerMode == SOFTWARE)
|
|
|
|
@@ -138,7 +130,7 @@ bool connectDevice()
|
|
|
|
|
MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
|
|
|
|
|
MV_CC_SetEnumValue(handle, "TriggerSource", MV_TRIGGER_SOURCE_LINE0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// //加载用户集,相机设置应当UserSet1
|
|
|
|
|
nRet = MV_CC_SetEnumValueByString(handle, "UserSetSelector", "UserSet1");
|
|
|
|
|
if (MV_OK != nRet)qDebug() << "Set UserSetSelector fail! nRet " << nRet;
|
|
|
|
@@ -146,24 +138,24 @@ bool connectDevice()
|
|
|
|
|
MV_CC_SetIntValueEx(handle, "GevHeartbeatTimeout", 3000);//心跳日志
|
|
|
|
|
|
|
|
|
|
nRet = MV_CC_RegisterImageCallBackEx(handle, ImageCallBackEx, handle);//注册回调
|
|
|
|
|
if (MV_OK != nRet)return false;
|
|
|
|
|
if (MV_OK != nRet)return false;
|
|
|
|
|
nRet = MV_CC_RegisterExceptionCallBack(handle, ReconnectDevice, NULL);//断线重连
|
|
|
|
|
if (MV_OK != nRet)return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MV_CC_StartGrabbing(handle);
|
|
|
|
|
cameraStatus.store(CONNECTED);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
void SetExposureTime(float exposureValue)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "[INFO] " << "exposureValue:" << exposureValue;
|
|
|
|
|
qDebug() << "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;
|
|
|
|
|
qDebug() << "GainValue:" << GainValue;
|
|
|
|
|
MV_CC_SetEnumValue(handle, "GainAuto", 0);
|
|
|
|
|
MV_CC_SetFloatValue(handle, "Gain", GainValue);
|
|
|
|
|
}
|
|
|
|
@@ -171,14 +163,14 @@ void SetGain(float GainValue)
|
|
|
|
|
//断线重连
|
|
|
|
|
void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) {
|
|
|
|
|
|
|
|
|
|
qDebug() << "[Error] " << " MV camera disconnects!";
|
|
|
|
|
qDebug() << " MV camera disconnects!";
|
|
|
|
|
|
|
|
|
|
if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT && cameraStatus.load() == CONNECTED) {
|
|
|
|
|
|
|
|
|
|
// 防止重复启动重连线程
|
|
|
|
|
bool expected = false;
|
|
|
|
|
if (!reconnecting.compare_exchange_strong(expected, true)) {
|
|
|
|
|
qDebug() << "[Warning] Reconnect already in progress, skipping duplicate request";
|
|
|
|
|
qDebug() << "Reconnect already in progress, skipping duplicate request";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -206,7 +198,7 @@ void __stdcall ReconnectDevice(unsigned int nMsgType, void* pUser) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果runFlag为false,线程退出
|
|
|
|
|
qDebug() << "[Info] reconnect thread stopped (runFlag=false)";
|
|
|
|
|
qDebug() << "reconnect thread stopped (runFlag=false)";
|
|
|
|
|
cameraStatus.store(DISCONNECTED);
|
|
|
|
|
reconnecting.store(false);
|
|
|
|
|
}).detach();
|
|
|
|
@@ -258,7 +250,7 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra
|
|
|
|
|
unsigned int nConvertDataSize = 0;
|
|
|
|
|
nConvertDataSize = pFrameInfo0->nWidth * pFrameInfo0->nHeight * 3;
|
|
|
|
|
|
|
|
|
|
// ch:像素格式转换 | en:Convert pixel format
|
|
|
|
|
// ch:像素格式转换 | en:Convert pixel format
|
|
|
|
|
MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };
|
|
|
|
|
|
|
|
|
|
frameNum = pFrameInfo0->nFrameNum; //ch:帧号 | en:frame number
|
|
|
|
@@ -291,7 +283,7 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra
|
|
|
|
|
queuepic.dequeue();
|
|
|
|
|
pData0 = { 0 };
|
|
|
|
|
double time_End = (double)clock();
|
|
|
|
|
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms"
|
|
|
|
|
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " checkImg getImg,Time:" << (time_End - time_Start) << "ms"
|
|
|
|
|
<< "--CameraName:" << QString::fromStdString(Username) << " imgIndex:" << imgIndex << "nFrameNum : " << frameNum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -299,7 +291,7 @@ void __stdcall ImageCallBackEx(unsigned char* pData0, MV_FRAME_OUT_INFO_EX* pFra
|
|
|
|
|
void CloseDevice()
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(handleMutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果 handle 已经为空,直接返回
|
|
|
|
|
if (handle == nullptr)
|
|
|
|
|
return;
|
|
|
|
@@ -307,19 +299,19 @@ void CloseDevice()
|
|
|
|
|
// 使用 SDK 正确的停止/关闭/销毁流程,避免使用 CloseHandle 等不匹配的 API
|
|
|
|
|
int nRet = MV_CC_StopGrabbing(handle);
|
|
|
|
|
if (MV_OK != nRet) {
|
|
|
|
|
qDebug() << "[Warning] MV_CC_StopGrabbing failed, nRet=" << nRet;
|
|
|
|
|
qDebug() << "MV_CC_StopGrabbing failed, nRet=" << nRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nRet = MV_CC_CloseDevice(handle);
|
|
|
|
|
if (MV_OK != nRet) {
|
|
|
|
|
qDebug() << "[Warning] MV_CC_CloseDevice failed, nRet=" << nRet;
|
|
|
|
|
qDebug() << "MV_CC_CloseDevice failed, nRet=" << nRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nRet = MV_CC_DestroyHandle(handle);
|
|
|
|
|
if (MV_OK != nRet) {
|
|
|
|
|
qDebug() << "[Warning] MV_CC_DestroyHandle failed, nRet=" << nRet;
|
|
|
|
|
qDebug() << "MV_CC_DestroyHandle failed, nRet=" << nRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handle = nullptr;
|
|
|
|
|
}
|
|
|
|
|
Hd_CameraModule_HIK_General::Hd_CameraModule_HIK_General() {
|
|
|
|
@@ -328,15 +320,15 @@ Hd_CameraModule_HIK_General::Hd_CameraModule_HIK_General() {
|
|
|
|
|
Hd_CameraModule_HIK_General::~Hd_CameraModule_HIK_General()
|
|
|
|
|
{
|
|
|
|
|
runFlag = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 等待重连线程结束
|
|
|
|
|
int waitCount = 0;
|
|
|
|
|
while (reconnecting.load() && waitCount < 50) { // 最多等待5秒
|
|
|
|
|
qDebug() << "[Info] Waiting for reconnect thread to finish...";
|
|
|
|
|
qDebug() << "Waiting for reconnect thread to finish...";
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
|
waitCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CloseDevice();
|
|
|
|
|
if (n_mutex)
|
|
|
|
|
{
|
|
|
|
@@ -344,7 +336,7 @@ Hd_CameraModule_HIK_General::~Hd_CameraModule_HIK_General()
|
|
|
|
|
n_mutex = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qDebug() << "[INFO] " << " delete success!";
|
|
|
|
|
qDebug() << " delete success!";
|
|
|
|
|
}
|
|
|
|
|
//从类中读数据到实例对象
|
|
|
|
|
bool Hd_CameraModule_HIK_General::readData(std::vector<cv::Mat>& mat, QByteArray& data)
|
|
|
|
@@ -357,7 +349,7 @@ bool Hd_CameraModule_HIK_General::readData(std::vector<cv::Mat>& mat, QByteArray
|
|
|
|
|
cv::Mat img = queuepic.dequeue();
|
|
|
|
|
mat.push_back(img);
|
|
|
|
|
queuepic.clear();
|
|
|
|
|
qDebug() << "[INFO] " << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex;
|
|
|
|
|
qDebug() << __FUNCTION__ << " line:" << __LINE__ << " checkImg readData--CameraName:" << QString::fromStdString(Username) << "--imgIndex : " << imgIndex;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -368,7 +360,7 @@ bool Hd_CameraModule_HIK_General::writeData(std::vector<cv::Mat>& mat, QByteArra
|
|
|
|
|
if (data.contains("deviceList")) {
|
|
|
|
|
auto result = QByteArrayToMV_CC_DeviceInfoList(data.mid(10));
|
|
|
|
|
if (result.nDeviceNum != 0) {
|
|
|
|
|
m_stDevList = result;
|
|
|
|
|
appHikDeviceListCache().setDeviceInfoList(result);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -394,7 +386,7 @@ bool Hd_CameraModule_HIK_General::initParas(QByteArray& initData)
|
|
|
|
|
{
|
|
|
|
|
QByteArrayList valueList = initData.split('#');
|
|
|
|
|
if (valueList.size() < 3) {
|
|
|
|
|
qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!参数数量不满足";
|
|
|
|
|
qDebug() << " Hd_CameraModule_HIK initParas fail--params error!参数数量不满足";
|
|
|
|
|
lastError = "参数数量不满足";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@@ -408,7 +400,7 @@ bool Hd_CameraModule_HIK_General::initParas(QByteArray& initData)
|
|
|
|
|
else if (triggerModeStr == "EMPTY")
|
|
|
|
|
triggerMode = EMPTY;
|
|
|
|
|
else {
|
|
|
|
|
qDebug() << "[Error] " << " Hd_CameraModule_HIK initParas fail--params error!触发模式参数错误";
|
|
|
|
|
qDebug() << " Hd_CameraModule_HIK initParas fail--params error!触发模式参数错误";
|
|
|
|
|
lastError = "触发模式参数错误";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@@ -421,7 +413,7 @@ bool Hd_CameraModule_HIK_General::initParas(QByteArray& initData)
|
|
|
|
|
|
|
|
|
|
bool Hd_CameraModule_HIK_General::run()
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "[INFO] " << " run start" << QString::fromStdString(Username);
|
|
|
|
|
qDebug() << " run start" << QString::fromStdString(Username);
|
|
|
|
|
if (triggerMode == SOFTWARE)
|
|
|
|
|
MV_CC_SetCommandValue(handle, "TriggerSoftware");
|
|
|
|
|
try
|
|
|
|
@@ -443,7 +435,7 @@ bool Hd_CameraModule_HIK_General::run()
|
|
|
|
|
}
|
|
|
|
|
catch (QString ev)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "[Error] " << " ev:" << ev;
|
|
|
|
|
qDebug() << " ev:" << ev;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@@ -458,7 +450,7 @@ bool Hd_CameraModule_HIK_General::checkStatus()
|
|
|
|
|
|
|
|
|
|
Hd_CameraModule_HIK_General* create()
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "[INFO] " << "Hd_CameraModule_HIK create success!";
|
|
|
|
|
qDebug() << "Hd_CameraModule_HIK create success!";
|
|
|
|
|
return new Hd_CameraModule_HIK_General;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -469,5 +461,5 @@ void destory(Hd_CameraModule_HIK_General* ptr)
|
|
|
|
|
delete ptr;
|
|
|
|
|
ptr = nullptr;
|
|
|
|
|
}
|
|
|
|
|
qDebug() << "[INFO] " << "Hd_CameraModule_HIK destory success!";
|
|
|
|
|
}
|
|
|
|
|
qDebug() << "Hd_CameraModule_HIK destory success!";
|
|
|
|
|
}
|
|
|
|
|