2022-06-13 12:01:30 +08:00
|
|
|
|
#include "Header_Files/ximeaimager.h"
|
|
|
|
|
|
|
|
|
|
XimeaImager::XimeaImager()
|
|
|
|
|
{
|
|
|
|
|
m_buffer=nullptr;
|
|
|
|
|
m_bRecordControl=false;
|
|
|
|
|
m_iFrameCounter=0;
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=100;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2022-12-06 14:50:18 +08:00
|
|
|
|
QString ximeaCfgFile = "/media/nvme/300TC/config/ximea.cfg";
|
2022-10-09 23:00:15 +08:00
|
|
|
|
m_configfile.setConfigfilePath(ximeaCfgFile.toStdString());
|
2022-08-15 17:36:19 +08:00
|
|
|
|
if(!m_configfile.isConfigfileExist())
|
|
|
|
|
m_configfile.createConfigFile();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
m_configfile.parseConfigfile();
|
2023-06-28 11:59:46 +08:00
|
|
|
|
m_configfile.getWindowOffsety_HeightOfSpectral(m_iOffsetyOfSpectralBin1, m_iHeightOfSpectralBin1, "bin1");
|
|
|
|
|
m_configfile.getWindowOffsety_HeightOfSpectral(m_iOffsetyOfSpectralBin2, m_iHeightOfSpectralBin2, "bin2");
|
|
|
|
|
//检查 ximea.cfg 是否满足要求
|
|
|
|
|
if(m_iOffsetyOfSpectralBin2 != m_iOffsetyOfSpectralBin1 / 2)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"ximea.cfg 错误:m_iOffsetyOfSpectralBin2 != m_iOffsetyOfSpectralBin1 / 2!"<<std::endl;
|
|
|
|
|
}
|
|
|
|
|
if(m_iOffsetyOfSpectralBin2 % 2 != 0)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"ximea.cfg 错误:m_iOffsetyOfSpectralBin2 不是 2 的倍数,ximea相机不接受!"<<std::endl;
|
|
|
|
|
}
|
|
|
|
|
if(m_iHeightOfSpectralBin1 < m_iHeightOfSpectralBin2 * 2)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"ximea.cfg 错误:bin1 波段数小于 bin2 波段数的 2 倍!"<<std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-29 13:46:40 +08:00
|
|
|
|
QString ximeaParamCfgFile = "/media/nvme/300TC/config/ximeaParam.cfg";
|
|
|
|
|
m_parameterConfigfile.setConfigfilePath(ximeaParamCfgFile.toStdString());
|
|
|
|
|
if(!m_parameterConfigfile.isConfigfileExist())
|
|
|
|
|
m_parameterConfigfile.createConfigFile();
|
|
|
|
|
m_parameterConfigfile.parseConfigfile();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
|
2022-08-15 17:36:19 +08:00
|
|
|
|
m_recordTempThread=new QThread();
|
2023-09-13 17:08:17 +08:00
|
|
|
|
m_ximeaTemperature = new RecordXimeaTemperature(&m_imager, this);
|
2022-08-15 17:36:19 +08:00
|
|
|
|
m_ximeaTemperature->moveToThread(m_recordTempThread);
|
|
|
|
|
m_recordTempThread->start();
|
|
|
|
|
|
|
|
|
|
connect(this, SIGNAL(recordXimeaTemperatureSignal(QString)),m_ximeaTemperature, SLOT(recordTemperature(QString)));
|
2022-12-24 16:59:41 +08:00
|
|
|
|
|
|
|
|
|
writeData2DiskThread = new QThread();
|
|
|
|
|
writeData2Disk = new WriteData2Disk();
|
|
|
|
|
writeData2Disk->moveToThread(writeData2DiskThread);
|
|
|
|
|
writeData2DiskThread->start(QThread::HighestPriority);
|
|
|
|
|
connect(this, SIGNAL(startWriteDiskSignal()), writeData2Disk, SLOT(write2Disk()));
|
|
|
|
|
|
|
|
|
|
m_pool = new MemoryPool<DataBuffer>;
|
|
|
|
|
q = new queue<DataBuffer *>;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
m_qFrameCounter = new queue<int>;
|
2023-03-19 16:44:12 +08:00
|
|
|
|
|
|
|
|
|
m_rgbImage = new rgbImage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XimeaImager::~XimeaImager()
|
|
|
|
|
{
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XimeaImager::openImger()
|
|
|
|
|
{
|
2022-06-22 21:45:22 +08:00
|
|
|
|
if(m_iImagerState != 100)//如果相机已经打开或者已经出错,就直接返回
|
2022-06-13 12:01:30 +08:00
|
|
|
|
{
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//std::cout<<"XimeaImager::openImger111111111111111111111:正在打开相机!"<<std::endl;
|
|
|
|
|
m_imager.connect();
|
|
|
|
|
|
2022-10-13 16:30:40 +08:00
|
|
|
|
bool ret, ret1, ret2;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
2022-10-13 16:30:40 +08:00
|
|
|
|
int spatialBin;
|
|
|
|
|
int spectralBin;
|
|
|
|
|
ret1 = m_configfile.getspatialBin(spatialBin);
|
|
|
|
|
ret2 = m_configfile.getSpectralBin(spectralBin);
|
|
|
|
|
if (ret1 & ret2)
|
2022-08-15 17:36:19 +08:00
|
|
|
|
{
|
2022-10-13 16:30:40 +08:00
|
|
|
|
bool haha = m_imager.setSpectralBin(spectralBin);
|
|
|
|
|
bool haha2 = m_imager.setSpatialBin(spatialBin);
|
2023-06-27 14:01:19 +08:00
|
|
|
|
|
|
|
|
|
emit binSignal(spatialBin, spectralBin);
|
2023-06-30 15:21:23 +08:00
|
|
|
|
std::cout<<"spectralBin:"<< spectralBin <<std::endl;
|
|
|
|
|
std::cout<<"spatialBin:"<< spatialBin <<std::endl;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2022-08-01 19:10:25 +08:00
|
|
|
|
float gain, offset;//用于生成头文件中的波长信息
|
2023-06-28 11:59:46 +08:00
|
|
|
|
ret = m_configfile.getGainOffsetOfSpectralBin1(gain, offset);
|
2022-08-15 17:36:19 +08:00
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
m_imager.setGainOffset(gain, offset);
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2022-08-01 19:10:25 +08:00
|
|
|
|
int width = 0, offsetx = 0, height = 0, offsety = 0;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
ret = m_configfile.getEffectiveWindow(width, offsetx, height, offsety);
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
m_imager.setEffectiveWindow(offsetx, width, offsety, height);
|
2023-03-19 16:44:12 +08:00
|
|
|
|
m_rgbImage->SetRgbImageWidthAndHeight(height, width, 20);
|
|
|
|
|
std::cout<<"height:"<< height <<std::endl;
|
|
|
|
|
std::cout<<"width:"<< width <<std::endl;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
std::cout<<"每帧字节数:"<< width * height * 2 <<std::endl;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-22 23:23:32 +08:00
|
|
|
|
// int width_roi = 0, offsetx_roi = 0;
|
|
|
|
|
// ret = m_configfile.getEffectiveWindowRoi(width_roi, offsetx_roi);
|
|
|
|
|
// if (ret)
|
|
|
|
|
// {
|
|
|
|
|
// m_imager.setEffectiveWindowRoi(offsetx_roi, width_roi);
|
|
|
|
|
// }
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
int bufferPolicy, acqBufferSize;
|
|
|
|
|
ret1 = m_configfile.getBufferPolicy(bufferPolicy);
|
|
|
|
|
if (ret1)
|
|
|
|
|
{
|
|
|
|
|
m_imager.setBufferPolicy(bufferPolicy);
|
|
|
|
|
}
|
|
|
|
|
ret1 = m_configfile.getAcqBufferSize(acqBufferSize);
|
|
|
|
|
if (ret1)
|
|
|
|
|
{
|
|
|
|
|
m_imager.setAcqBufferSize(acqBufferSize);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-29 13:46:40 +08:00
|
|
|
|
if (m_parameterConfigfile.isConfigfileExist())
|
|
|
|
|
{
|
|
|
|
|
int frameRate;
|
|
|
|
|
m_parameterConfigfile.getFrameRate(frameRate);
|
|
|
|
|
setFramerate(frameRate);
|
|
|
|
|
|
|
|
|
|
float exposeTime;
|
|
|
|
|
m_parameterConfigfile.getExposeTime(exposeTime);
|
|
|
|
|
wrapSetExposureTime(exposeTime);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
setFramerate(100);
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2022-08-01 19:10:25 +08:00
|
|
|
|
//经验证:frameSizeManual和frameSizeAuto相等
|
2022-06-13 12:01:30 +08:00
|
|
|
|
int frameSizeManual = m_imager.get_band_count()*m_imager.get_sample_count()*2;
|
|
|
|
|
int frameSizeAuto = m_imager.getBufferSizeOfOneFrame();
|
|
|
|
|
|
|
|
|
|
m_iFrameSizeInByte = frameSizeAuto;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
std::cout<<"每一帧的字节数:-------------------------------"<< m_iFrameSizeInByte <<std::endl;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
|
|
|
|
m_buffer = new unsigned short[m_iFrameSizeInByte];
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState = 101;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
2022-10-09 23:00:15 +08:00
|
|
|
|
QDateTime curDateTime = QDateTime::currentDateTime();
|
|
|
|
|
QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss");
|
2023-09-13 17:08:17 +08:00
|
|
|
|
m_ximeaTemperatureCSVPath = QDir::cleanPath(QString::fromStdString("/media/nvme/300TC/programRunLog/ximeaTemperature") + QDir::separator() + "ximeaTemperature_" + currentTime + ".csv");
|
2022-10-09 23:00:15 +08:00
|
|
|
|
// m_ximeaTemperatureCSVPath = "/home/ximeaTemperature.csv";
|
2022-08-15 17:36:19 +08:00
|
|
|
|
emit recordXimeaTemperatureSignal(m_ximeaTemperatureCSVPath);
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"XimeaImager::openImger----------------:ERROR!"<<std::endl;
|
|
|
|
|
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
|
|
|
|
}
|
|
|
|
|
catch(char const* e1)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"char *e---------!"<<std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XimeaImager::closeImger()
|
|
|
|
|
{
|
2022-08-15 17:36:19 +08:00
|
|
|
|
m_ximeaTemperature->stopRecordTemperature();
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
if(m_iImagerState==100)
|
2022-06-13 12:01:30 +08:00
|
|
|
|
{
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
m_imager.disconnect();
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=100;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"XimeaImager::closeImger-------------------!"<<std::endl;
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
|
|
|
|
}
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XimeaImager::setFramerate(double framerate)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
m_imager.set_framerate(framerate);
|
|
|
|
|
|
2023-09-04 18:03:20 +08:00
|
|
|
|
int exposureTimeInUs = getExposureTime();
|
|
|
|
|
|
2023-08-29 13:46:40 +08:00
|
|
|
|
int maxExposureTimeInUs=1/framerate*1000000;
|
2023-09-04 18:03:20 +08:00
|
|
|
|
|
|
|
|
|
if (exposureTimeInUs > maxExposureTimeInUs)
|
|
|
|
|
{
|
|
|
|
|
wrapSetExposureTime(maxExposureTimeInUs);
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=102;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
2023-05-24 16:38:10 +08:00
|
|
|
|
|
|
|
|
|
emit frameRateSignal(framerate);
|
2023-08-29 13:46:40 +08:00
|
|
|
|
|
|
|
|
|
m_parameterConfigfile.setFrameRate(framerate);
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double XimeaImager::getExposureTime()
|
|
|
|
|
{
|
|
|
|
|
double exposureTime;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
exposureTime=m_imager.get_integration_time();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return exposureTime;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double XimeaImager::setExposureTime(float exposureTime_in_us)
|
|
|
|
|
{
|
|
|
|
|
double integrationTime2Return;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//计算最大积分时间
|
|
|
|
|
float currentFramerate=getFramerate();
|
|
|
|
|
float maxExposureTime_in_us=1/currentFramerate*1000000;
|
|
|
|
|
|
|
|
|
|
//确保设置的积分时间比最大积分时间小
|
|
|
|
|
if(exposureTime_in_us<maxExposureTime_in_us)
|
|
|
|
|
{
|
|
|
|
|
m_imager.set_integration_time(exposureTime_in_us);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_imager.set_integration_time(maxExposureTime_in_us);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//返回设置的积分时间
|
|
|
|
|
integrationTime2Return=m_imager.get_integration_time();
|
2023-08-29 13:46:40 +08:00
|
|
|
|
m_parameterConfigfile.setExposeTime(integrationTime2Return);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
|
|
|
|
|
return integrationTime2Return;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-24 16:38:10 +08:00
|
|
|
|
int XimeaImager::wrapSetExposureTime(float exposureTime_in_us)
|
2023-03-19 16:44:12 +08:00
|
|
|
|
{
|
2023-05-24 16:38:10 +08:00
|
|
|
|
double exposureTime = setExposureTime(exposureTime_in_us);
|
|
|
|
|
|
|
|
|
|
m_imager.start();
|
|
|
|
|
m_imager.get_frame(m_buffer);
|
|
|
|
|
m_imager.stop();
|
|
|
|
|
|
|
|
|
|
int maxValueOfOneFrame = getMaxValueOfOneFrame((short unsigned int*)m_imager.m_image.bp,m_imager.get_band_count()*m_imager.get_sample_count());
|
2023-03-19 16:44:12 +08:00
|
|
|
|
|
|
|
|
|
m_iImagerState=103;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
2023-05-24 16:38:10 +08:00
|
|
|
|
|
2023-09-04 18:03:20 +08:00
|
|
|
|
emit autoExposeMaxValueOfOneFrame(maxValueOfOneFrame, exposureTime);
|
2023-05-24 16:38:10 +08:00
|
|
|
|
|
|
|
|
|
return maxValueOfOneFrame;
|
2023-03-19 16:44:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
double XimeaImager::autoExposure()
|
|
|
|
|
{
|
|
|
|
|
double exposureTime;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//方式1:在曝光时的帧率前提下,从最大曝光时间开始循环采集
|
|
|
|
|
int maxValueOfOneFrame;
|
|
|
|
|
float suitableMaxValue=4095 * 0.8;
|
|
|
|
|
|
|
|
|
|
double framerate = m_imager.get_framerate();
|
2023-03-19 16:44:12 +08:00
|
|
|
|
double maxExposureTime = 1/framerate*1000000*0.95;//0.95目的:避免曝光时间超过最大,而造成帧率降低
|
2022-06-13 12:01:30 +08:00
|
|
|
|
exposureTime=setExposureTime(maxExposureTime);
|
|
|
|
|
|
|
|
|
|
bool bIsAutoExposureOk=false;
|
|
|
|
|
while(!bIsAutoExposureOk)
|
|
|
|
|
{
|
2022-12-06 14:50:18 +08:00
|
|
|
|
std::cout<<"自动曝光本次时间为:"<< exposureTime <<std::endl;
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
m_imager.start();
|
|
|
|
|
m_imager.get_frame(m_buffer);
|
|
|
|
|
m_imager.stop();
|
|
|
|
|
|
2022-12-07 19:33:51 +08:00
|
|
|
|
maxValueOfOneFrame=getMaxValueOfOneFrame((short unsigned int*)m_imager.m_image.bp,m_imager.get_band_count()*m_imager.get_sample_count());
|
2023-05-24 16:38:10 +08:00
|
|
|
|
printf("本帧最大值为: %d.\n",maxValueOfOneFrame);
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
|
|
|
|
if(maxValueOfOneFrame <= suitableMaxValue)
|
|
|
|
|
{
|
|
|
|
|
bIsAutoExposureOk=true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
exposureTime = exposureTime*0.95;
|
|
|
|
|
exposureTime=setExposureTime(exposureTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// //方式2:
|
|
|
|
|
// int baseExposureTime_in_us=5000;
|
|
|
|
|
// float suitableMaxValue=4095 * 0.8;
|
|
|
|
|
// int maxValueOfOneFrame;
|
|
|
|
|
|
|
|
|
|
// setExposureTime(baseExposureTime_in_us);
|
|
|
|
|
|
|
|
|
|
// m_imager.start();
|
|
|
|
|
// m_imager.get_frame(m_buffer);
|
|
|
|
|
// m_imager.stop();
|
|
|
|
|
|
|
|
|
|
// std::cout<<"1111111111111111111111111111111111!"<<std::endl;
|
|
|
|
|
// maxValueOfOneFrame=getMaxValueOfOneFrame(m_buffer,m_imager.get_band_count()*m_imager.get_sample_count());
|
|
|
|
|
// std::cout<<"2222222222222222222222222222222222!"<<std::endl;
|
|
|
|
|
|
|
|
|
|
// float scale=suitableMaxValue/maxValueOfOneFrame;
|
|
|
|
|
// float suitableExposureTime=baseExposureTime_in_us * scale;
|
|
|
|
|
// exposureTime=setExposureTime(suitableExposureTime);
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=103;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
2023-09-04 18:03:20 +08:00
|
|
|
|
emit autoExposeMaxValueOfOneFrame(maxValueOfOneFrame, exposureTime);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
|
|
|
|
|
std::cout<<"自动曝光完成!"<<std::endl;
|
|
|
|
|
return exposureTime;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
|
|
|
|
|
std::cout<<"自动曝光失败!"<<std::endl;
|
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-01 19:10:25 +08:00
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double XimeaImager::getFramerate()
|
|
|
|
|
{
|
|
|
|
|
double framerate;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
framerate=m_imager.get_framerate();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
|
|
|
|
|
return framerate;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
|
|
|
|
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XimeaImager::setGain(double gain)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
m_imager.set_gain(gain);
|
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double XimeaImager::getGain()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return m_imager.get_gain();
|
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getSampleCount()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-08-01 19:10:25 +08:00
|
|
|
|
int sampleCount=m_imager.get_sample_count();
|
|
|
|
|
return sampleCount;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getBandCount()
|
|
|
|
|
{
|
|
|
|
|
int bandCount;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
bandCount=m_imager.get_band_count();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return bandCount;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getWindowStartBand()
|
|
|
|
|
{
|
|
|
|
|
int windowStartBand;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
windowStartBand=m_imager.get_start_band();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return windowStartBand;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getWindowEndBand()
|
|
|
|
|
{
|
|
|
|
|
int windowEndBand;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
windowEndBand=m_imager.get_end_band();
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return windowEndBand;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double XimeaImager::geWavelengthAtBand(int x)
|
|
|
|
|
{
|
|
|
|
|
double wavelengthAtBand;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
wavelengthAtBand=m_imager.get_wavelength_at_band(x);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return wavelengthAtBand;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
2022-08-01 19:10:25 +08:00
|
|
|
|
return -1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getMaxValueOfOneFrame(unsigned short * data, int numberOfPixel)
|
|
|
|
|
{
|
|
|
|
|
//排序
|
|
|
|
|
//bubbleSort(data,1000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//计算出最大的10%值的平均值
|
|
|
|
|
unsigned short maxValue=0;
|
|
|
|
|
for(int i=0;i<numberOfPixel;i++)
|
|
|
|
|
{
|
2022-08-15 17:36:19 +08:00
|
|
|
|
// std::cout<<"像素值为:"<< *(data + i) <<std::endl;
|
|
|
|
|
if (*(data + i)>maxValue)
|
|
|
|
|
{
|
|
|
|
|
//std::cout<<"像素值为:"<< *(data + i) <<std::endl;
|
|
|
|
|
maxValue=*(data + i);
|
|
|
|
|
}
|
|
|
|
|
if (*(data + i)==65535)
|
2022-06-13 12:01:30 +08:00
|
|
|
|
{
|
2022-08-15 17:36:19 +08:00
|
|
|
|
int a=0;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return maxValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getImagerState() const
|
|
|
|
|
{
|
|
|
|
|
return m_iImagerState;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
double XimeaImager::calculateTimeDifferenceBetweenSbgAndximea(XI_IMG * image, double timeDifferenceBetweenSbgAndOS)
|
|
|
|
|
{
|
|
|
|
|
printf("XimeaImager::calculateTimeDifferenceBetweenSystemAndximea--timeDifferenceBetweenSbgAndOS: %f s\n", timeDifferenceBetweenSbgAndOS);
|
|
|
|
|
|
|
|
|
|
double ximeaTime=image->tsSec + image->tsUSec/1000000;
|
|
|
|
|
|
|
|
|
|
printf("XimeaImager::calculateTimeDifferenceBetweenSystemAndximea--ximeaTime: %f s\n", ximeaTime);
|
|
|
|
|
|
|
|
|
|
//获取系统时间(纳秒)
|
|
|
|
|
struct timespec systemTime;
|
|
|
|
|
clock_gettime(CLOCK_REALTIME,&systemTime);
|
|
|
|
|
tm systemTime_rili;
|
|
|
|
|
localtime_r(&systemTime.tv_sec, &systemTime_rili);
|
|
|
|
|
|
|
|
|
|
double secondSystem=(systemTime_rili.tm_mday-1)*24*60*60+systemTime_rili.tm_hour*60*60+systemTime_rili.tm_min*60+systemTime_rili.tm_sec;
|
|
|
|
|
double timeOS=secondSystem+static_cast<double>(systemTime.tv_nsec)/1000000000;
|
|
|
|
|
|
|
|
|
|
printf("XimeaImager::calculateTimeDifferenceBetweenSystemAndximea--osTime: %f s\n", timeOS);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//计算系统时间和gps时间之间的差距
|
|
|
|
|
double timeDifferenceBetweenSbgAndximea = timeOS - timeDifferenceBetweenSbgAndOS - ximeaTime;
|
|
|
|
|
|
|
|
|
|
printf("XimeaImager::calculateTimeDifferenceBetweenSystemAndximea--timeDifferenceBetweenSbgAndximea: %f s\n", timeDifferenceBetweenSbgAndximea);
|
|
|
|
|
|
|
|
|
|
return timeDifferenceBetweenSbgAndximea;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString baseFileName)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-06-22 21:45:22 +08:00
|
|
|
|
if(m_iImagerState <= 99 || m_iImagerState==100 || m_iImagerState==104)
|
2022-06-13 12:01:30 +08:00
|
|
|
|
{
|
2023-09-01 11:35:13 +08:00
|
|
|
|
printf("已经开始采集----------------------------!\n");
|
2022-06-13 12:01:30 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_iImagerStateTemp=m_iImagerState;
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=104;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
2023-03-19 16:44:12 +08:00
|
|
|
|
char * timeFormat="%Y%m%d_%H%M%S";
|
|
|
|
|
QString timeStr = formatTimeStr(timeFormat);
|
|
|
|
|
printf("开始采集:%s!\n", timeStr.toStdString().c_str());
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
m_iFrameCounter=0;
|
|
|
|
|
m_bRecordControl=true;
|
|
|
|
|
|
|
|
|
|
m_baseFileName=baseFileName;
|
|
|
|
|
|
2023-09-04 18:03:20 +08:00
|
|
|
|
std::cout << "帧率为:" << getFramerate() << "hz" <<std::endl;
|
|
|
|
|
std::cout << "曝光时间为:" << getExposureTime() << "μs" <<std::endl;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
|
|
|
|
using namespace std;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
// ofstream timesFileHandle(timesFileName.toStdString()+"_ofstream");
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
int number_WriteDisk = 100;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
writeData2Disk->setParm(q, m_qFrameCounter,m_baseFileName,m_iFrameSizeInByte, number_WriteDisk, m_pool, m_rgbImage);
|
2023-10-18 11:39:01 +08:00
|
|
|
|
// emit startWriteDiskSignal();
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
int indexofbuff;
|
|
|
|
|
DataBuffer * buffer;
|
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
QString timesFileName=m_baseFileName+".times";
|
|
|
|
|
FILE *hHimesFile=fopen(timesFileName.toStdString().c_str(),"w+");
|
|
|
|
|
// ofstream timesFile(timesFileName.toStdString());
|
|
|
|
|
double timeDifferenceBetweenSbgAndXimea;
|
|
|
|
|
double * sbgTimeBuffer = new double[number_WriteDisk];
|
|
|
|
|
|
2023-10-18 11:39:01 +08:00
|
|
|
|
QString imageFileName=m_baseFileName+".bil";
|
|
|
|
|
FILE *hFile=fopen(imageFileName.toStdString().c_str(),"w+b");
|
|
|
|
|
double * imageBuffer = new double[number_WriteDisk];
|
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
m_imager.start();
|
2022-06-13 12:01:30 +08:00
|
|
|
|
struct timeval timeStart, timeEnd;
|
|
|
|
|
double runTime=0;
|
|
|
|
|
gettimeofday(&timeStart, NULL);
|
|
|
|
|
while (m_bRecordControl)
|
|
|
|
|
{
|
|
|
|
|
unsigned short *x=m_imager.get_frame(m_buffer);
|
2023-06-21 16:43:33 +08:00
|
|
|
|
m_iFrameCounter+=1;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
if (m_iFrameCounter == 1)
|
|
|
|
|
{
|
|
|
|
|
timeDifferenceBetweenSbgAndXimea = calculateTimeDifferenceBetweenSbgAndximea(&m_imager.m_image, TimeDifferenceBetweensOSAndSbg);
|
|
|
|
|
}
|
2023-10-18 11:39:01 +08:00
|
|
|
|
fwrite(m_imager.m_image.bp,1,m_iFrameSizeInByte, hFile);
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
indexofbuff = m_iFrameCounter % number_WriteDisk;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
if (indexofbuff == 0)
|
|
|
|
|
{
|
2023-06-30 15:21:23 +08:00
|
|
|
|
sbgTimeBuffer[number_WriteDisk - 1] = getSbgTime(&m_imager.m_image, timeDifferenceBetweenSbgAndXimea);
|
2023-06-21 16:43:33 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-06-30 15:21:23 +08:00
|
|
|
|
sbgTimeBuffer[indexofbuff - 1] = getSbgTime(&m_imager.m_image, timeDifferenceBetweenSbgAndXimea);
|
2023-06-21 16:43:33 +08:00
|
|
|
|
}
|
2022-12-24 16:59:41 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
if (indexofbuff == 0)
|
|
|
|
|
{
|
2023-06-30 15:21:23 +08:00
|
|
|
|
for (int i = 0; i < number_WriteDisk; ++i)
|
|
|
|
|
{
|
|
|
|
|
fprintf(hHimesFile,"%f\n",sbgTimeBuffer[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (indexofbuff != 0)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < indexofbuff; ++i)
|
|
|
|
|
{
|
|
|
|
|
fprintf(hHimesFile,"%f\n",sbgTimeBuffer[i]);
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
std::cout << "没凑满: " << indexofbuff <<std::endl;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
gettimeofday(&timeEnd, NULL);
|
|
|
|
|
runTime = (timeEnd.tv_sec - timeStart.tv_sec ) + (double)(timeEnd.tv_usec -timeStart.tv_usec)/1000000;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
m_imager.stop();
|
2023-06-25 21:20:45 +08:00
|
|
|
|
writeData2Disk->exitWriteData2Disk();
|
2023-06-30 15:21:23 +08:00
|
|
|
|
writeHdr();
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
delete[] sbgTimeBuffer;
|
2023-06-21 16:43:33 +08:00
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
double frameInTheory=runTime * getFramerate();
|
2023-06-21 16:43:33 +08:00
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
double frameLossed = m_imager.m_image.acq_nframe - m_iFrameCounter;
|
|
|
|
|
double frameLossRate = frameLossed / m_imager.m_image.acq_nframe;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
std::cout<<"当前采集文件为: "<<baseFileName.toStdString()<< ".bil" <<std::endl;
|
2023-09-13 17:08:17 +08:00
|
|
|
|
std::cout<<"采集时间为: "<<runTime/60<< " min" <<std::endl;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
std::cout<<"当前帧率为: "<<getFramerate() << "hz" <<std::endl;
|
|
|
|
|
std::cout<<"每秒数据量为: "<<getFramerate()*m_iFrameSizeInByte/(1024*1024)<<"MB"<<std::endl;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
std::cout<<"理论采集帧数为: "<<m_imager.m_image.acq_nframe<<std::endl;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
std::cout<<"实际采集帧数为:"<<m_iFrameCounter<<std::endl;
|
|
|
|
|
std::cout<<"丢失帧数为: "<<frameLossed<<std::endl;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
std::cout<<"丢帧率为: "<<frameLossRate * 100<< "%" <<std::endl;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
|
|
|
|
fclose(hHimesFile);
|
2023-10-18 11:39:01 +08:00
|
|
|
|
fclose(hFile);
|
2022-12-24 16:59:41 +08:00
|
|
|
|
// timesFileHandle.close();
|
2023-06-21 16:43:33 +08:00
|
|
|
|
// timesFile.close();
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-03-19 16:44:12 +08:00
|
|
|
|
timeStr = formatTimeStr(timeFormat);
|
|
|
|
|
printf("停止采集:%s!\n", timeStr.toStdString().c_str());
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
|
|
|
|
m_iImagerState=m_iImagerStateTemp;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
emit recordFinished();
|
|
|
|
|
}
|
|
|
|
|
catch(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
processXiApiErrorCodes(xiApiErrorCodes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XimeaImager::writeHdr()
|
|
|
|
|
{
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
QString hdrPath=m_baseFileName+".hdr";
|
|
|
|
|
|
|
|
|
|
ofstream hdrFileHandle(hdrPath.toStdString());
|
|
|
|
|
hdrFileHandle << "ENVI\n";
|
2023-03-19 16:44:12 +08:00
|
|
|
|
|
|
|
|
|
QString SN;
|
|
|
|
|
m_configfile.getSN(SN);
|
|
|
|
|
hdrFileHandle << "SN = " << SN.toStdString() << "\n";
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
hdrFileHandle << "interleave = bil\n";
|
|
|
|
|
hdrFileHandle << "byte order = 0\n";
|
|
|
|
|
hdrFileHandle << "data type = 2\n";
|
|
|
|
|
//hdrFileHandle << "bit depth = 12\n";
|
|
|
|
|
|
|
|
|
|
hdrFileHandle << "samples = " << getSampleCount() << "\n";
|
|
|
|
|
hdrFileHandle << "bands = " << getBandCount() << "\n";
|
|
|
|
|
hdrFileHandle << "lines = " << m_iFrameCounter << "\n";
|
|
|
|
|
hdrFileHandle << "sample binning = " << m_imager.getSpatialBin() << "\n";
|
|
|
|
|
hdrFileHandle << "spectral binning = " << m_imager.getSpectralBin() << "\n";
|
|
|
|
|
|
|
|
|
|
hdrFileHandle << "framerate = " << getFramerate() << "\n";
|
|
|
|
|
hdrFileHandle << "shutter = " << getExposureTime()/1000 << "\n";
|
|
|
|
|
hdrFileHandle << "shutter units = milliseconds\n";
|
|
|
|
|
hdrFileHandle << "gain = " << getGain() << "\n";
|
|
|
|
|
|
|
|
|
|
hdrFileHandle << "wavelength units = nanometers\n";
|
|
|
|
|
hdrFileHandle << "wavelength = {";
|
|
|
|
|
//hdrFileHandle << std::setprecision(5);
|
2023-06-28 11:59:46 +08:00
|
|
|
|
|
|
|
|
|
if (m_imager.getSpectralBin() == 1)
|
2022-06-13 12:01:30 +08:00
|
|
|
|
{
|
2023-06-28 11:59:46 +08:00
|
|
|
|
for (int i = getWindowStartBand(); i < getWindowEndBand(); i++)
|
|
|
|
|
{
|
|
|
|
|
hdrFileHandle << geWavelengthAtBand(i);
|
|
|
|
|
if (i < getWindowEndBand() - 1)
|
|
|
|
|
hdrFileHandle << ", ";
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("头文件中写入了多少个波段:%d\n",i-getWindowStartBand()+1);//???????????????
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (m_imager.getSpectralBin() == 2)
|
|
|
|
|
{
|
|
|
|
|
int counter = 0;
|
|
|
|
|
for (int i = m_iOffsetyOfSpectralBin2; i < m_iOffsetyOfSpectralBin2 + m_iHeightOfSpectralBin2; i++)
|
2022-06-13 12:01:30 +08:00
|
|
|
|
{
|
2023-06-28 11:59:46 +08:00
|
|
|
|
if (i*2 + 1 > m_iOffsetyOfSpectralBin1 + m_iHeightOfSpectralBin1)
|
|
|
|
|
{
|
|
|
|
|
printf("XimeaImager::writeHdr 出现错误:窗口中,光谱 bin1 波段数小于 bin2 的 2 倍。\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hdrFileHandle << (geWavelengthAtBand(i*2) + geWavelengthAtBand(i*2 + 1)) / 2;
|
|
|
|
|
counter++;
|
|
|
|
|
if (i < m_iOffsetyOfSpectralBin2 + m_iHeightOfSpectralBin2 - 1)
|
|
|
|
|
hdrFileHandle << ", ";
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("头文件中写入了多少个波段:%d\n", counter);
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-28 11:59:46 +08:00
|
|
|
|
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
hdrFileHandle << "}\n";
|
|
|
|
|
hdrFileHandle.close();
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
/*
|
|
|
|
|
#define MM40_OK 0 //!< Function call succeeded
|
|
|
|
|
#define MM40_INVALID_HANDLE 1 //!< Invalid handle
|
|
|
|
|
#define MM40_READREG 2 //!< Register read error
|
|
|
|
|
#define MM40_WRITEREG 3 //!< Register write error
|
|
|
|
|
#define MM40_FREE_RESOURCES 4 //!< Freeing resources error
|
|
|
|
|
#define MM40_FREE_CHANNEL 5 //!< Freeing channel error
|
|
|
|
|
#define MM40_FREE_BANDWIDTH 6 //!< Freeing bandwith error
|
|
|
|
|
#define MM40_READBLK 7 //!< Read block error
|
|
|
|
|
#define MM40_WRITEBLK 8 //!< Write block error
|
|
|
|
|
#define MM40_NO_IMAGE 9 //!< No image
|
|
|
|
|
#define MM40_TIMEOUT 10 //!< Timeout
|
|
|
|
|
#define MM40_INVALID_ARG 11 //!< Invalid arguments supplied
|
|
|
|
|
#define MM40_NOT_SUPPORTED 12 //!< Not supported
|
|
|
|
|
#define MM40_ISOCH_ATTACH_BUFFERS 13 //!< Attach buffers error
|
|
|
|
|
#define MM40_GET_OVERLAPPED_RESULT 14 //!< Overlapped result
|
|
|
|
|
#define MM40_MEMORY_ALLOCATION 15 //!< Memory allocation error
|
|
|
|
|
#define MM40_DLLCONTEXTISNULL 16 //!< DLL context is NULL
|
|
|
|
|
#define MM40_DLLCONTEXTISNONZERO 17 //!< DLL context is non zero
|
|
|
|
|
#define MM40_DLLCONTEXTEXIST 18 //!< DLL context exists
|
|
|
|
|
#define MM40_TOOMANYDEVICES 19 //!< Too many devices connected
|
|
|
|
|
#define MM40_ERRORCAMCONTEXT 20 //!< Camera context error
|
|
|
|
|
#define MM40_UNKNOWN_HARDWARE 21 //!< Unknown hardware
|
|
|
|
|
#define MM40_INVALID_TM_FILE 22 //!< Invalid TM file
|
|
|
|
|
#define MM40_INVALID_TM_TAG 23 //!< Invalid TM tag
|
|
|
|
|
#define MM40_INCOMPLETE_TM 24 //!< Incomplete TM
|
|
|
|
|
#define MM40_BUS_RESET_FAILED 25 //!< Bus reset error
|
|
|
|
|
#define MM40_NOT_IMPLEMENTED 26 //!< Not implemented
|
|
|
|
|
#define MM40_SHADING_TOOBRIGHT 27 //!< Shading is too bright
|
|
|
|
|
#define MM40_SHADING_TOODARK 28 //!< Shading is too dark
|
|
|
|
|
#define MM40_TOO_LOW_GAIN 29 //!< Gain is too low
|
|
|
|
|
#define MM40_INVALID_BPL 30 //!< Invalid sensor defect correction list
|
|
|
|
|
#define MM40_BPL_REALLOC 31 //!< Error while sensor defect correction list reallocation
|
|
|
|
|
#define MM40_INVALID_PIXEL_LIST 32 //!< Invalid pixel list
|
|
|
|
|
#define MM40_INVALID_FFS 33 //!< Invalid Flash File System
|
|
|
|
|
#define MM40_INVALID_PROFILE 34 //!< Invalid profile
|
|
|
|
|
#define MM40_INVALID_CALIBRATION 35 //!< Invalid calibration
|
|
|
|
|
#define MM40_INVALID_BUFFER 36 //!< Invalid buffer
|
|
|
|
|
#define MM40_INVALID_DATA 38 //!< Invalid data
|
|
|
|
|
#define MM40_TGBUSY 39 //!< Timing generator is busy
|
|
|
|
|
#define MM40_IO_WRONG 40 //!< Wrong operation open/write/read/close
|
|
|
|
|
#define MM40_ACQUISITION_ALREADY_UP 41 //!< Acquisition already started
|
|
|
|
|
#define MM40_OLD_DRIVER_VERSION 42 //!< Old version of device driver installed to the system.
|
|
|
|
|
#define MM40_GET_LAST_ERROR 43 //!< To get error code please call GetLastError function.
|
|
|
|
|
#define MM40_CANT_PROCESS 44 //!< Data cannot be processed
|
|
|
|
|
#define MM40_ACQUISITION_STOPED 45 //!< Acquisition is stopped. It needs to be started to perform operation.
|
|
|
|
|
#define MM40_ACQUISITION_STOPED_WERR 46 //!< Acquisition has been stopped with an error.
|
|
|
|
|
#define MM40_INVALID_INPUT_ICC_PROFILE 47 //!< Input ICC profile missing or corrupted
|
|
|
|
|
#define MM40_INVALID_OUTPUT_ICC_PROFILE 48 //!< Output ICC profile missing or corrupted
|
|
|
|
|
#define MM40_DEVICE_NOT_READY 49 //!< Device not ready to operate
|
|
|
|
|
#define MM40_SHADING_TOOCONTRAST 50 //!< Shading is too contrast
|
|
|
|
|
#define MM40_ALREADY_INITIALIZED 51 //!< Module already initialized
|
|
|
|
|
#define MM40_NOT_ENOUGH_PRIVILEGES 52 //!< Application does not have enough privileges (one or more app)
|
|
|
|
|
#define MM40_NOT_COMPATIBLE_DRIVER 53 //!< Installed driver is not compatible with current software
|
|
|
|
|
#define MM40_TM_INVALID_RESOURCE 54 //!< TM file was not loaded successfully from resources
|
|
|
|
|
#define MM40_DEVICE_HAS_BEEN_RESETED 55 //!< Device has been reset, abnormal initial state
|
|
|
|
|
#define MM40_NO_DEVICES_FOUND 56 //!< No Devices Found
|
|
|
|
|
#define MM40_RESOURCE_OR_FUNCTION_LOCKED 57 //!< Resource (device) or function locked by mutex
|
|
|
|
|
#define MM40_BUFFER_SIZE_TOO_SMALL 58 //!< Buffer provided by user is too small
|
|
|
|
|
#define MM40_COULDNT_INIT_PROCESSOR 59 //!< Could not initialize processor.
|
|
|
|
|
#define MM40_NOT_INITIALIZED 60 //!< The object/module/procedure/process being referred to has not been started.
|
|
|
|
|
#define MM40_RESOURCE_NOT_FOUND 61 //!< Resource not found(could be processor, file, item...).
|
|
|
|
|
*/
|
|
|
|
|
|
2022-06-13 12:01:30 +08:00
|
|
|
|
void XimeaImager::processXiApiErrorCodes(int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
using namespace std;
|
|
|
|
|
switch (xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Invalid handle!"<<std::endl;
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
break;
|
|
|
|
|
case 10:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Timeout!"<<std::endl;
|
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 11:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Invalid arguments supplied!"<<std::endl;
|
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
2022-08-15 17:36:19 +08:00
|
|
|
|
break;
|
|
|
|
|
case 12:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Not supported!"<<std::endl;
|
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
2022-06-22 21:45:22 +08:00
|
|
|
|
break;
|
|
|
|
|
case 15:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Memory allocation error!"<<std::endl;
|
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 56:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:NO_DEVICES_FOUND!"<<std::endl;
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 57:
|
|
|
|
|
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:RESOURCE_OR_FUNCTION_LOCKED!"<<std::endl;
|
2022-06-22 21:45:22 +08:00
|
|
|
|
m_iImagerState=xiApiErrorCodes;
|
2022-06-13 12:01:30 +08:00
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2023-06-21 16:43:33 +08:00
|
|
|
|
m_iImagerState=99;
|
|
|
|
|
emit ximeaImageStatus(m_iImagerState);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
writeXiApiErrorCodes("/media/nvme/300TC/ximeaError.txt", xiApiErrorCodes);
|
|
|
|
|
}
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
void XimeaImager::writeXiApiErrorCodes(QString filePath, int xiApiErrorCodes)
|
|
|
|
|
{
|
|
|
|
|
ofstream ximeaErrorFile(filePath.toStdString().c_str(),ios::app);
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
char * timeFormat="%Y%m%d_%H%M%S";
|
|
|
|
|
QString timeStr = formatTimeStr(timeFormat);
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
ximeaErrorFile<< timeStr.toStdString().c_str() << ": " << xiApiErrorCodes << "\n";
|
2022-06-13 12:01:30 +08:00
|
|
|
|
|
2023-06-21 16:43:33 +08:00
|
|
|
|
std::cout<<"XimeaImager::writeXiApiErrorCodes-----------:xiApiErrorCodes: "<<timeStr.toStdString().c_str()<< ": " << xiApiErrorCodes<<std::endl;
|
|
|
|
|
|
|
|
|
|
ximeaErrorFile.close();
|
2022-06-13 12:01:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XimeaImager::stopRecord()
|
|
|
|
|
{
|
|
|
|
|
//printf("Stop record!\n");
|
|
|
|
|
m_bRecordControl=false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int XimeaImager::getFrameCounter()
|
|
|
|
|
{
|
|
|
|
|
return m_iFrameCounter;
|
|
|
|
|
}
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
DataBuffer::DataBuffer()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DataBuffer::~DataBuffer()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-13 17:08:17 +08:00
|
|
|
|
RecordXimeaTemperature::RecordXimeaTemperature(Iris::IrisXimeaImager * imager, XimeaImager * ximeaImager)
|
2022-08-15 17:36:19 +08:00
|
|
|
|
{
|
|
|
|
|
m_imager = imager;
|
|
|
|
|
m_bIsRecord = true;
|
2023-09-13 17:08:17 +08:00
|
|
|
|
|
|
|
|
|
m_ximeaImager = ximeaImager;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RecordXimeaTemperature::stopRecordTemperature()
|
|
|
|
|
{
|
|
|
|
|
m_bIsRecord = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RecordXimeaTemperature::recordTemperature(QString filePath= nullptr)
|
|
|
|
|
{
|
|
|
|
|
if(filePath== nullptr)
|
|
|
|
|
filePath="ximeaTemperature.csv";
|
2023-09-13 17:08:17 +08:00
|
|
|
|
QList<QString> fileInfo = getFileInfo(filePath);
|
|
|
|
|
bool ret = createDir(fileInfo[0]);
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
2023-09-13 17:08:17 +08:00
|
|
|
|
ofstream ximeaTemperatureFile(filePath.toStdString().c_str(),ios::app);
|
|
|
|
|
int counter = 0;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
while(m_bIsRecord)
|
|
|
|
|
{
|
2023-09-13 17:08:17 +08:00
|
|
|
|
counter++;
|
|
|
|
|
|
2022-08-15 17:36:19 +08:00
|
|
|
|
float temp = m_imager->getTemperature();
|
2023-09-13 17:08:17 +08:00
|
|
|
|
if(temp > 80 && m_ximeaImager->getImagerState() == 104)
|
|
|
|
|
{
|
2023-10-18 11:37:02 +08:00
|
|
|
|
ximeaTemperatureFile.flush();
|
2023-09-13 17:08:17 +08:00
|
|
|
|
system("/home/300tc/projects/udpClient/udpClient 127.0.0.1 9,0");
|
|
|
|
|
}
|
|
|
|
|
if(temp > 90)
|
|
|
|
|
{
|
2023-10-18 11:37:02 +08:00
|
|
|
|
ximeaTemperatureFile.flush();
|
2023-09-13 17:08:17 +08:00
|
|
|
|
system("/home/300tc/projects/udpClient/udpClient 127.0.0.1 2");
|
|
|
|
|
}
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
|
|
|
|
QDateTime curDateTime = QDateTime::currentDateTime();
|
|
|
|
|
QString currentTime = curDateTime.toString("yyyy/MM/dd hh:mm:ss");
|
|
|
|
|
|
|
|
|
|
ximeaTemperatureFile << currentTime.toStdString() << "," << temp << "\n";
|
|
|
|
|
|
|
|
|
|
// std::cout<<"RecordXimeaTemperature::recordTemperature----------------:ximea Temperature is "<< temp <<std::endl;
|
2023-09-13 17:08:17 +08:00
|
|
|
|
// std::cout<<"RecordXimeaTemperature::recordTemperature----------------:ximea state is "<< m_ximeaImager->getImagerState() <<std::endl;
|
2022-08-15 17:36:19 +08:00
|
|
|
|
|
2023-09-13 17:08:17 +08:00
|
|
|
|
if (counter % 60 == 0)
|
|
|
|
|
{
|
|
|
|
|
ximeaTemperatureFile.flush();
|
|
|
|
|
}
|
2022-08-15 17:36:19 +08:00
|
|
|
|
sleep(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_bIsRecord = true;
|
|
|
|
|
|
|
|
|
|
ximeaTemperatureFile.close();
|
|
|
|
|
}
|
2022-12-24 16:59:41 +08:00
|
|
|
|
|
|
|
|
|
WriteData2Disk::WriteData2Disk()
|
|
|
|
|
{
|
2023-06-25 21:20:45 +08:00
|
|
|
|
isExitWriteData2Disk = false;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WriteData2Disk::write2Disk()
|
|
|
|
|
{
|
|
|
|
|
QString imageFileName=m_QbaseFileName+".bil";
|
2023-07-14 16:33:37 +08:00
|
|
|
|
FILE *hFile=fopen(imageFileName.toStdString().c_str(),"w+b");
|
2023-07-04 21:22:38 +08:00
|
|
|
|
|
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
int frameCounter = 0;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
int frameNumber;
|
2023-06-21 16:43:33 +08:00
|
|
|
|
unsigned short * dataBuffer = new unsigned short[m_iFrameSizeInByte/2*m_iNumber_WriteDisk];
|
2023-06-25 21:20:45 +08:00
|
|
|
|
isExitWriteData2Disk = false;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
r_qtx.lock();
|
|
|
|
|
bool bempty=m_q->empty();
|
|
|
|
|
r_qtx.unlock();
|
2023-06-25 21:20:45 +08:00
|
|
|
|
if(bempty && isExitWriteData2Disk)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"WriteData2Disk::write2Disk-----------------------队列为空,采集线程已经退出!"<<std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-07-14 09:21:58 +08:00
|
|
|
|
else if(isExitWriteData2Disk)
|
|
|
|
|
{
|
|
|
|
|
std::cout<<"WriteData2Disk::write2Disk-----------------------isExitWriteData2Disk:true"<<std::endl;
|
|
|
|
|
std::cout<<"WriteData2Disk::write2Disk-----------------------队列大小"<<m_q->size()<<std::endl;
|
|
|
|
|
}
|
2023-06-25 21:20:45 +08:00
|
|
|
|
else if(bempty && !isExitWriteData2Disk)
|
2022-12-24 16:59:41 +08:00
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-07-14 09:21:58 +08:00
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
r_qtx.lock();
|
|
|
|
|
DataBuffer * buffer = m_q->front();
|
2023-06-30 15:21:23 +08:00
|
|
|
|
int frameNumber = m_qFrameCounter->front();
|
|
|
|
|
memcpy(dataBuffer,buffer->data,m_iFrameSizeInByte*frameNumber);
|
2022-12-24 16:59:41 +08:00
|
|
|
|
// m_pool->destroy(m_q->front());
|
|
|
|
|
m_pool->deleteElement(buffer);
|
|
|
|
|
m_q->pop();
|
2023-06-30 15:21:23 +08:00
|
|
|
|
m_qFrameCounter->pop();
|
2022-12-24 16:59:41 +08:00
|
|
|
|
r_qtx.unlock();
|
|
|
|
|
|
2023-03-19 16:44:12 +08:00
|
|
|
|
//构造rgb图像,用于推流到m300遥控器
|
2023-05-24 16:38:10 +08:00
|
|
|
|
// m_rgbImage->FillRgbImage(dataBuffer);
|
2023-03-19 16:44:12 +08:00
|
|
|
|
|
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
// std::cout<<"WriteData2Disk::write2Disk-----------------------正在写磁盘!" << m_pool->max_size() <<std::endl;//
|
2023-07-14 16:33:37 +08:00
|
|
|
|
fwrite(dataBuffer,1,m_iFrameSizeInByte*frameNumber, hFile);
|
2023-07-04 21:22:38 +08:00
|
|
|
|
|
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
frameCounter++;
|
|
|
|
|
}
|
2023-03-19 16:44:12 +08:00
|
|
|
|
m_rgbImage->m_VideoWriter.release();
|
2023-07-14 16:33:37 +08:00
|
|
|
|
fclose(hFile);
|
2023-06-30 15:21:23 +08:00
|
|
|
|
delete[] dataBuffer;
|
2023-03-19 16:44:12 +08:00
|
|
|
|
|
2023-07-04 21:22:38 +08:00
|
|
|
|
|
2022-12-24 16:59:41 +08:00
|
|
|
|
std::cout<<"WriteData2Disk::write2Disk-----------------------写磁盘线程将退出,内存池可达到的最多元素数:" << m_pool->max_size() <<std::endl;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
std::cout<<"WriteData2Disk::write2Disk-----------------------写磁盘线程将退出,fwrite 调用次数:" << frameCounter <<std::endl;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-25 21:20:45 +08:00
|
|
|
|
void WriteData2Disk::exitWriteData2Disk()
|
|
|
|
|
{
|
2023-07-14 09:21:58 +08:00
|
|
|
|
std::cout<< "执行函数:WriteData2Disk::exitWriteData2Disk" <<std::endl;
|
2023-06-25 21:20:45 +08:00
|
|
|
|
isExitWriteData2Disk = true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-30 15:21:23 +08:00
|
|
|
|
void WriteData2Disk::setParm(queue<DataBuffer *> * q, queue<int> * qFrameCounter, QString baseFileName, int frameSizeInByte, int number_WriteDisk, MemoryPool<DataBuffer> * pool, rgbImage * rgbImage)
|
2022-12-24 16:59:41 +08:00
|
|
|
|
{
|
|
|
|
|
m_q = q;
|
2023-06-30 15:21:23 +08:00
|
|
|
|
m_qFrameCounter = qFrameCounter;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
m_QbaseFileName = baseFileName;
|
|
|
|
|
m_iFrameSizeInByte = frameSizeInByte;
|
2023-06-21 16:43:33 +08:00
|
|
|
|
m_iNumber_WriteDisk = number_WriteDisk;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
|
|
|
|
|
m_pool = pool;
|
2023-03-19 16:44:12 +08:00
|
|
|
|
|
|
|
|
|
m_rgbImage = rgbImage;
|
2022-12-24 16:59:41 +08:00
|
|
|
|
}
|