Files
ximeaAirborneSystem/Source_Files/ximeaimager.cpp

579 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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,corning410bin1
// m_imager.setRoi(144,680,170,151);//sn008,corning410bin2
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;
}