300TC 机载系统 完整功能,(1)采集影像(2)采集和解析惯导数据(3)惯导磁场校正
This commit is contained in:
578
Source_Files/ximeaimager.cpp
Normal file
578
Source_Files/ximeaimager.cpp
Normal file
@ -0,0 +1,578 @@
|
||||
#include "Header_Files/ximeaimager.h"
|
||||
|
||||
XimeaImager::XimeaImager()
|
||||
{
|
||||
m_buffer=nullptr;
|
||||
m_bRecordControl=false;
|
||||
m_iFrameCounter=0;
|
||||
m_iImagerState=0;
|
||||
|
||||
//connect(this, SIGNAL(recordFinished()),this, SLOT());
|
||||
}
|
||||
|
||||
void XimeaImager::openImger()
|
||||
{
|
||||
if(m_iImagerState>0)
|
||||
{
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//std::cout<<"XimeaImager::openImger111111111111111111111:正在打开相机!"<<std::endl;
|
||||
m_imager.connect();
|
||||
|
||||
// bool haha = m_imager.setSpectralBin(2);
|
||||
// bool haha2 = m_imager.setSpatialBin(2);
|
||||
|
||||
//sn008_bin1
|
||||
float a=1.999564;
|
||||
float b=-279.893;
|
||||
// //sn008_bin2
|
||||
// float a = 3.99912794;
|
||||
// float b = -278.89317732225084;
|
||||
|
||||
m_imager.setGainOffset(a, b);
|
||||
|
||||
|
||||
//SN=008自己修改
|
||||
// int OffsetX=272;
|
||||
// int width=1392;
|
||||
//
|
||||
// int OffsetY=338;
|
||||
// int height=302;
|
||||
//
|
||||
// //SN=008标准
|
||||
// int OffsetX=288;//272
|
||||
// int width=1360;//是16的整数倍
|
||||
//
|
||||
// int OffsetY=340;
|
||||
// int height=300;//302
|
||||
|
||||
|
||||
// m_imager.setRoi(288,1360,348,300);//sn0098
|
||||
m_imager.setRoi(288,1360,340,300);//sn008,corning410,bin1
|
||||
// m_imager.setRoi(144,680,170,151);//sn008,corning410,bin2
|
||||
|
||||
setFramerate(100);
|
||||
|
||||
int frameSizeManual = m_imager.get_band_count()*m_imager.get_sample_count()*2;
|
||||
int frameSizeAuto = m_imager.getBufferSizeOfOneFrame();
|
||||
|
||||
m_iFrameSizeInByte = frameSizeAuto;
|
||||
|
||||
m_buffer = new unsigned short[m_iFrameSizeInByte];
|
||||
|
||||
m_iImagerState = 1;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
}
|
||||
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()
|
||||
{
|
||||
if(m_iImagerState==0)
|
||||
{
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_imager.disconnect();
|
||||
|
||||
m_iImagerState=0;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
std::cout<<"XimeaImager::closeImger-------------------!"<<std::endl;
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
}
|
||||
|
||||
void XimeaImager::setFramerate(double framerate)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_imager.set_framerate(framerate);
|
||||
|
||||
int maxExposureTimeInUs=1/framerate*1000000*0.8;
|
||||
setExposureTime(maxExposureTimeInUs);
|
||||
// setExposureTime(1000);
|
||||
|
||||
m_iImagerState=2;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
}
|
||||
|
||||
double XimeaImager::getExposureTime()
|
||||
{
|
||||
double exposureTime;
|
||||
try
|
||||
{
|
||||
exposureTime=m_imager.get_integration_time();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return exposureTime;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
|
||||
return integrationTime2Return;
|
||||
}
|
||||
|
||||
double XimeaImager::autoExposure()
|
||||
{
|
||||
double exposureTime;
|
||||
try
|
||||
{
|
||||
//方式1:在曝光时的帧率前提下,从最大曝光时间开始循环采集
|
||||
int maxValueOfOneFrame;
|
||||
float suitableMaxValue=4095 * 0.8;
|
||||
|
||||
double framerate = m_imager.get_framerate();
|
||||
double maxExposureTime = 1/framerate*1000000;
|
||||
exposureTime=setExposureTime(maxExposureTime);
|
||||
|
||||
bool bIsAutoExposureOk=false;
|
||||
while(!bIsAutoExposureOk)
|
||||
{
|
||||
m_imager.start();
|
||||
m_imager.get_frame(m_buffer);
|
||||
m_imager.stop();
|
||||
|
||||
maxValueOfOneFrame=getMaxValueOfOneFrame(m_buffer,m_imager.get_band_count()*m_imager.get_sample_count());
|
||||
|
||||
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);
|
||||
|
||||
m_iImagerState=3;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
std::cout<<"自动曝光完成!"<<std::endl;
|
||||
return exposureTime;
|
||||
}
|
||||
|
||||
double XimeaImager::getFramerate()
|
||||
{
|
||||
double framerate;
|
||||
|
||||
try
|
||||
{
|
||||
framerate=m_imager.get_framerate();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return framerate;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int XimeaImager::getSampleCount()
|
||||
{
|
||||
int sampleCount;
|
||||
|
||||
try
|
||||
{
|
||||
sampleCount=m_imager.get_sample_count();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
int XimeaImager::getBandCount()
|
||||
{
|
||||
int bandCount;
|
||||
|
||||
try
|
||||
{
|
||||
bandCount=m_imager.get_band_count();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return bandCount;
|
||||
}
|
||||
|
||||
int XimeaImager::getWindowStartBand()
|
||||
{
|
||||
int windowStartBand;
|
||||
|
||||
try
|
||||
{
|
||||
windowStartBand=m_imager.get_start_band();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return windowStartBand;
|
||||
}
|
||||
|
||||
int XimeaImager::getWindowEndBand()
|
||||
{
|
||||
int windowEndBand;
|
||||
|
||||
try
|
||||
{
|
||||
windowEndBand=m_imager.get_end_band();
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return windowEndBand;
|
||||
}
|
||||
|
||||
double XimeaImager::geWavelengthAtBand(int x)
|
||||
{
|
||||
double wavelengthAtBand;
|
||||
|
||||
try
|
||||
{
|
||||
wavelengthAtBand=m_imager.get_wavelength_at_band(x);
|
||||
}
|
||||
catch(int xiApiErrorCodes)
|
||||
{
|
||||
processXiApiErrorCodes(xiApiErrorCodes);
|
||||
}
|
||||
|
||||
return wavelengthAtBand;
|
||||
}
|
||||
|
||||
int XimeaImager::getMaxValueOfOneFrame(unsigned short * data, int numberOfPixel)
|
||||
{
|
||||
//排序
|
||||
//bubbleSort(data,1000);
|
||||
|
||||
|
||||
//计算出最大的10%值的平均值
|
||||
unsigned short maxValue=0;
|
||||
for(int i=0;i<numberOfPixel;i++)
|
||||
{
|
||||
if (data[i]>maxValue)
|
||||
{
|
||||
maxValue=data[i];
|
||||
}
|
||||
}
|
||||
printf("本帧最大值为: %d.\n",maxValue);
|
||||
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
int XimeaImager::getImagerState() const
|
||||
{
|
||||
return m_iImagerState;
|
||||
}
|
||||
|
||||
void XimeaImager::startRecord(double TimeDifferenceBetweensOSAndSbg,QString baseFileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_iImagerState==4 || m_iImagerState==0 || m_iImagerState>=21)
|
||||
{
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_iImagerStateTemp=m_iImagerState;
|
||||
|
||||
m_iImagerState=4;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
printf("开始采集!\n");
|
||||
m_iFrameCounter=0;
|
||||
m_bRecordControl=true;
|
||||
|
||||
m_imager.start();
|
||||
|
||||
m_baseFileName=baseFileName;
|
||||
|
||||
QString imageFileName=m_baseFileName+".bil";
|
||||
QString timesFileName=m_baseFileName+".times";
|
||||
|
||||
//
|
||||
FILE *hFile=fopen(imageFileName.toStdString().c_str(),"w+b");
|
||||
FILE *hHimesFile=fopen(timesFileName.toStdString().c_str(),"w+");
|
||||
|
||||
using namespace std;
|
||||
ofstream timesFileHandle(timesFileName.toStdString()+"_ofstream");
|
||||
|
||||
|
||||
struct timeval timeStart, timeEnd;
|
||||
double runTime=0;
|
||||
gettimeofday(&timeStart, NULL);
|
||||
|
||||
while (m_bRecordControl)
|
||||
{
|
||||
unsigned short *x=m_imager.get_frame(m_buffer);
|
||||
|
||||
//fwrite(m_buffer,2,getBandCount()*getSampleCount(),hFile);
|
||||
fwrite(m_buffer,1,m_iFrameSizeInByte,hFile);//*********************************
|
||||
//fflush(hFile);//只保证了将IO缓冲写入系统缓冲中,使IO读操作能成功,但系统什么时候写入磁盘,由系统决定,一般是达到一定量时系统他就写入磁盘。
|
||||
//sync();//强制系统将系统文件缓冲的内容写入磁盘
|
||||
|
||||
m_iFrameCounter+=1;
|
||||
|
||||
|
||||
double sbgTime=getSbgTime(TimeDifferenceBetweensOSAndSbg);
|
||||
|
||||
fprintf(hHimesFile,"%f\n",sbgTime);
|
||||
//fwrite(&sbgTime,sizeof(double),1,hHimesFile);
|
||||
|
||||
timesFileHandle << sbgTime << "\n";
|
||||
|
||||
// std::cout<<"XimeaImager::startRecord---std::cout: "<<sbgTime<<std::endl;
|
||||
|
||||
// //用于测试是否漏帧
|
||||
// if(m_iFrameCounter==getFramerate()*20)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
|
||||
// unsigned char pixel = *(unsigned char*)image.bp;//Default value: XI_MONO8
|
||||
// unsigned short pixel =*(unsigned short*)image.bp;//XI_RAW16
|
||||
// printf("Image %d (%dx%d) received from camera. First pixel value: %d\n", m_iFrameCounter, (int)image.width, (int)image.height, pixel);
|
||||
}
|
||||
|
||||
gettimeofday(&timeEnd, NULL);
|
||||
runTime = (timeEnd.tv_sec - timeStart.tv_sec ) + (double)(timeEnd.tv_usec -timeStart.tv_usec)/1000000;
|
||||
|
||||
double frameInTheory=runTime * getFramerate();
|
||||
double frameLossed=frameInTheory - m_iFrameCounter;
|
||||
double frameLossRate=frameLossed / frameInTheory;
|
||||
|
||||
std::cout<<"当前采集文件为: "<<baseFileName.toStdString()<<std::endl;
|
||||
std::cout<<"采集时间为: "<<runTime<<std::endl;
|
||||
std::cout<<"理论采集帧数为: "<<frameInTheory<<std::endl;
|
||||
std::cout<<"实际采集帧数为:"<<m_iFrameCounter<<std::endl;
|
||||
std::cout<<"丢失帧数为: "<<frameLossed<<std::endl;
|
||||
std::cout<<"丢帧率为: "<<frameLossRate<<std::endl;
|
||||
|
||||
fclose(hFile);
|
||||
fclose(hHimesFile);
|
||||
timesFileHandle.close();
|
||||
|
||||
printf("Stopping acquisition...\n");
|
||||
m_imager.stop();
|
||||
|
||||
writeHdr();
|
||||
|
||||
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";
|
||||
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);
|
||||
for (int i = getWindowStartBand(); i < getWindowEndBand(); i++)
|
||||
{
|
||||
hdrFileHandle << geWavelengthAtBand(i);
|
||||
if (i < getWindowEndBand() - 1)
|
||||
hdrFileHandle << ", ";
|
||||
else
|
||||
{
|
||||
printf("头文件中写入了多少个波段:%d\n",i-getWindowStartBand()+1);//???????????????
|
||||
}
|
||||
}
|
||||
hdrFileHandle << "}\n";
|
||||
hdrFileHandle.close();
|
||||
}
|
||||
|
||||
void XimeaImager::processXiApiErrorCodes(int xiApiErrorCodes)
|
||||
{
|
||||
using namespace std;
|
||||
switch (xiApiErrorCodes)
|
||||
{
|
||||
case 1:
|
||||
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:Invalid handle!"<<std::endl;
|
||||
m_iImagerState=0;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
break;
|
||||
case 56:
|
||||
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:NO_DEVICES_FOUND!"<<std::endl;
|
||||
m_iImagerState=0;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
break;
|
||||
case 57:
|
||||
std::cout<<"XimeaImager::processXiApiErrorCodes-----------:RESOURCE_OR_FUNCTION_LOCKED!"<<std::endl;
|
||||
m_iImagerState=22;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
|
||||
break;
|
||||
default:
|
||||
QString ximeaError="ximeaError.txt";
|
||||
ofstream ximeaErrorFile(ximeaError.toStdString().c_str(),ios::app);
|
||||
|
||||
ximeaErrorFile<< xiApiErrorCodes << "\n";
|
||||
|
||||
ximeaErrorFile.close();
|
||||
|
||||
|
||||
|
||||
m_iImagerState=21;
|
||||
emit ximeaImageStatus(m_iImagerState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XimeaImager::stopRecord()
|
||||
{
|
||||
//printf("Stop record!\n");
|
||||
m_bRecordControl=false;
|
||||
}
|
||||
|
||||
int XimeaImager::getFrameCounter()
|
||||
{
|
||||
return m_iFrameCounter;
|
||||
}
|
Reference in New Issue
Block a user