#include "camera.h" #include "thread.h" #include // 使用std::vector存储所有帧的数据 //外部引用的标志位 save_flag 存图标志位 RGB 光谱是否需要保存图 (不能单独存一个 RGB 或 光谱 , 只能要存全存 除非再加标志位) //spec_flag 没用到 extern int save_flag; extern bool spec_flag; tomato tomato; //RGB相机的回调函数 void __stdcall onImageDataCallBackFunc(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser); void __stdcall onOfflineCallBackFunc(unsigned int nMsgType, void* pUser); void __stdcall onImageDataCallBackFunc1(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser); void __stdcall onOfflineCallBackFunc1(unsigned int nMsgType, void* pUser); void __stdcall onImageDataCallBackFunc2(unsigned char * pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser); void __stdcall onOfflineCallBackFunc2(unsigned int nMsgType, void* pUser); //光谱相机的回调函数 extern void __stdcall RTRGBViewCallback(void* pContext, unsigned char* pRData, unsigned char* pGData, unsigned char* pBData, unsigned long dataLength); extern void __stdcall RTSpecStreamingCallback(void *pContext, unsigned char *pData, unsigned long dataLength); //三个相机是否连接上的标志位 在 initcamera 里面的 opencamera 函数有返回值 负责修改 ui界面的 "是否连接" 标志位 int camStatusret; int camStatusret1; int camStatusret2; //果蔬标志位 extern int fruit_flag; CameraL::CameraL(QObject *parent) : QObject(parent) { } //初始化相机 bool CameraL::initCameraL() { /* * 枚举设备 * */ int device_num = enum_device(); qDebug()<<"找到相机: "<SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff; //根据第四位 ip 来创建 camera_handle //camera_handle 相当于 一个指向相机的指针 这个指针就代表相机 switch (ip4) { case 100: MV_CC_CreateHandle(&camera_handle1, device_list.pDeviceInfo[i]); break; case 150: MV_CC_CreateHandle(&camera_handle, device_list.pDeviceInfo[i]); break; case 200: MV_CC_CreateHandle(&camera_handle2, device_list.pDeviceInfo[i]); break; default: break; } pstDeviceInfo++; } return true; } bool CameraL::open_camera() { int ret = MV_CC_OpenDevice(camera_handle); int ret1 = MV_CC_OpenDevice(camera_handle1); int ret2 = MV_CC_OpenDevice(camera_handle2); camStatusret2=0; camStatusret1=0; camStatusret=0; if(ret != MV_OK||ret1 != MV_OK||ret2 != MV_OK) { return false; camStatusret2=0; camStatusret1=0; camStatusret=0; } return true; } bool CameraL::open_camera2() { /* * 导入配置文件(相机) **/ bool isOk = import_config_file(); // set_ROI(0, 668, 1000, 2448); if(!isOk) { qDebug()<<"import config file failed"; if(camera_handle != NULL) { destroy_handle(); } if(camera_handle1 != NULL) { destroy_handle1(); } if(camera_handle2 != NULL) { destroy_handle2(); } return false;; } isOk = register_image_callback(onImageDataCallBackFunc,onImageDataCallBackFunc1,onImageDataCallBackFunc2); qDebug()<<"注册回调成功: "<<"isOk: "< m_iHeight || m_cslGreen > m_iHeight || m_cslBlue > m_iHeight || m_cslRed <= 0 || m_cslGreen <= 0 || m_cslBlue <= 0) { m_cslRed = m_iHeight * 3 / 4; m_cslGreen = m_iHeight / 2; m_cslBlue = m_iHeight / 4; } RTSetRGBselect(m_cslRed, m_cslGreen, m_cslBlue); RTAddRGBCallback(RTRGBViewCallback, nullptr); RTAddStreamingCallback(RTSpecStreamingCallback,nullptr); return true; } //这个 cal 函数 是光谱相机的回调函数内触发的一个槽函数 可以在 thread 里面的光谱相机的回调找到 bool SpecCamera::cal(unsigned char *pData) { test_count++; //假设筛选后的ROI 为 30 * 100 宽 * 谱段数 //按右上角为数据初始点 900像素点 每一行第 900 个像素点 第 73 个谱段 unsigned short* spec_total_data = new unsigned short[30 * 13]; //宽 * 谱段数 unsigned short* spec_short_data = (unsigned short *)pData; int Band[13]={8,9,10,48,49,50,77,80,103,108,115,143,145}; for(int k=0;k<13;k++) { memcpy(spec_total_data + k * 30, spec_short_data + 900 + (Band[k] - 1) * 2048, 30 * sizeof(unsigned short)); } if (test_count < 26) { SpecData_vector.push_back(spec_total_data); } else { delete[] spec_total_data; // 释放内存以防止内存泄漏 } return true; } //光谱相机内置函数 不用管 bool SpecCamera::stop_capture() { if (RTIsCameraWorking()) { RTStopSingleCapture(); } return true; } bool SpecCamera::trigger_open() { bool ret = RT_SetBool(L"Camera.TriggerIn", true); //设置相机外触发 if(ret==false) { qDebug()<<"trigger is not open:"<