#include "Header_Files/ximeaimager.h" XimeaImager::XimeaImager() { m_buffer=nullptr; m_bRecordControl=false; m_iFrameCounter=0; m_iImagerState=100; QString ximeaCfgFile = "/media/nvme/300TC/config/ximea.cfg"; m_configfile.setConfigfilePath(ximeaCfgFile.toStdString()); if(!m_configfile.isConfigfileExist()) m_configfile.createConfigFile(); m_configfile.parseConfigfile(); 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!"<moveToThread(m_recordTempThread); m_recordTempThread->start(); connect(this, SIGNAL(recordXimeaTemperatureSignal(QString)),m_ximeaTemperature, SLOT(recordTemperature(QString))); writeData2DiskThread = new QThread(); writeData2Disk = new WriteData2Disk(); writeData2Disk->moveToThread(writeData2DiskThread); writeData2DiskThread->start(QThread::HighestPriority); connect(this, SIGNAL(startWriteDiskSignal()), writeData2Disk, SLOT(write2Disk())); m_pool = new MemoryPool; q = new queue; m_qFrameCounter = new queue; m_rgbImage = new rgbImage(); } XimeaImager::~XimeaImager() { } void XimeaImager::openImger() { if(m_iImagerState != 100)//如果相机已经打开或者已经出错,就直接返回 { emit ximeaImageStatus(m_iImagerState); return; } try { //std::cout<<"XimeaImager::openImger111111111111111111111:正在打开相机!"<SetRgbImageWidthAndHeight(height, width, 20); std::cout<<"height:"<< height <stopRecordTemperature(); if(m_iImagerState==100) { emit ximeaImageStatus(m_iImagerState); return; } try { m_imager.disconnect(); m_iImagerState=100; emit ximeaImageStatus(m_iImagerState); } catch(int xiApiErrorCodes) { std::cout<<"XimeaImager::closeImger-------------------!"<maxValue) { //std::cout<<"像素值为:"<< *(data + i) <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(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; } void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString baseFileName) { m_ximeaTemperature->stopRecordTemperature();//开始采集影像前,停止获取相机的温度,以免降低帧率; try { if(m_iImagerState <= 99 || m_iImagerState==100 || m_iImagerState==104) { emit ximeaImageStatus(m_iImagerState); return; } m_iImagerStateTemp=m_iImagerState; m_iImagerState=104; emit ximeaImageStatus(m_iImagerState); char * timeFormat="%Y%m%d_%H%M%S"; QString timeStr = formatTimeStr(timeFormat); printf("开始采集:%s!\n", timeStr.toStdString().c_str()); m_iFrameCounter=0; m_bRecordControl=true; m_baseFileName=baseFileName; std::cout << "曝光时间为:" << getExposureTime()/1000 << "ms" <setParm(q, m_qFrameCounter,m_baseFileName,m_iFrameSizeInByte, number_WriteDisk, m_pool, m_rgbImage); emit startWriteDiskSignal(); int indexofbuff; DataBuffer * buffer; 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]; m_imager.start(); struct timeval timeStart, timeEnd; double runTime=0; gettimeofday(&timeStart, NULL); while (m_bRecordControl) { unsigned short *x=m_imager.get_frame(m_buffer); m_iFrameCounter+=1; if (m_iFrameCounter == 1) { timeDifferenceBetweenSbgAndXimea = calculateTimeDifferenceBetweenSbgAndximea(&m_imager.m_image, TimeDifferenceBetweensOSAndSbg); } indexofbuff = m_iFrameCounter % number_WriteDisk; if (indexofbuff == 1) { r_qtx.lock(); buffer = m_pool->newElement(); r_qtx.unlock(); } if (indexofbuff == 0) { memcpy((void *)buffer->data + (number_WriteDisk - 1) * m_iFrameSizeInByte,m_imager.m_image.bp,m_iFrameSizeInByte); sbgTimeBuffer[number_WriteDisk - 1] = getSbgTime(&m_imager.m_image, timeDifferenceBetweenSbgAndXimea); } else { memcpy((void *)buffer->data + (indexofbuff - 1) * m_iFrameSizeInByte,m_imager.m_image.bp,m_iFrameSizeInByte); sbgTimeBuffer[indexofbuff - 1] = getSbgTime(&m_imager.m_image, timeDifferenceBetweenSbgAndXimea); } if (indexofbuff == 0) { r_qtx.lock(); q->push(buffer); m_qFrameCounter->push(number_WriteDisk); r_qtx.unlock(); for (int i = 0; i < number_WriteDisk; ++i) { fprintf(hHimesFile,"%f\n",sbgTimeBuffer[i]); } } } if (indexofbuff != 0) { r_qtx.lock(); q->push(buffer); m_qFrameCounter->push(indexofbuff); r_qtx.unlock(); for (int i = 0; i < indexofbuff; ++i) { fprintf(hHimesFile,"%f\n",sbgTimeBuffer[i]); } std::cout << "没凑满: " << indexofbuff <exitWriteData2Disk(); writeHdr(); delete[] sbgTimeBuffer; double frameInTheory=runTime * getFramerate(); double frameLossed = m_imager.m_image.acq_nframe - m_iFrameCounter; double frameLossRate = frameLossed / m_imager.m_image.acq_nframe; std::cout<<"当前采集文件为: "< 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); } } } hdrFileHandle << "}\n"; hdrFileHandle.close(); } /* #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...). */ void XimeaImager::processXiApiErrorCodes(int xiApiErrorCodes) { using namespace std; switch (xiApiErrorCodes) { case 1: std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Invalid handle!"<getTemperature(); 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 <empty(); r_qtx.unlock(); if(bempty && isExitWriteData2Disk) { std::cout<<"WriteData2Disk::write2Disk-----------------------队列为空,采集线程已经退出!"<front(); int frameNumber = m_qFrameCounter->front(); memcpy(dataBuffer,buffer->data,m_iFrameSizeInByte*frameNumber); // m_pool->destroy(m_q->front()); m_pool->deleteElement(buffer); m_q->pop(); m_qFrameCounter->pop(); r_qtx.unlock(); //构造rgb图像,用于推流到m300遥控器 // m_rgbImage->FillRgbImage(dataBuffer); // std::cout<<"WriteData2Disk::write2Disk-----------------------正在写磁盘!" << m_pool->max_size() <m_VideoWriter.release(); // fclose(hFile); delete[] dataBuffer; // if (munmap(addr, fileSize) == -1) { // std::cerr << "Error un-mmapping the file\n"; // } // Resize the file to 4096 bytes if (ftruncate(fd, sizeWrited2disk) == -1) { std::cerr << "Error calling ftruncate()\n"; return; } // Remap the file with the new size addr = mremap(addr, fileSize, sizeWrited2disk, MREMAP_MAYMOVE); if (addr == MAP_FAILED) { std::cerr << "Error calling mremap()\n"; return; } if (munmap(addr, sizeWrited2disk) == -1) { std::cerr << "Error un-mmapping the file\n"; } close(fd); std::cout<<"WriteData2Disk::write2Disk-----------------------写磁盘线程将退出,内存池可达到的最多元素数:" << m_pool->max_size() < * q, queue * qFrameCounter, QString baseFileName, int frameSizeInByte, int number_WriteDisk, MemoryPool * pool, rgbImage * rgbImage) { m_q = q; m_qFrameCounter = qFrameCounter; m_QbaseFileName = baseFileName; m_iFrameSizeInByte = frameSizeInByte; m_iNumber_WriteDisk = number_WriteDisk; m_pool = pool; m_rgbImage = rgbImage; }