419 lines
8.4 KiB
C++
419 lines
8.4 KiB
C++
#include "stdafx.h"
|
||
#include <iostream>
|
||
#include <fstream>
|
||
#include <iomanip>
|
||
#include <exception>
|
||
#include "ResononNirImager.h"
|
||
|
||
ResononNirImager::ResononNirImager()
|
||
{
|
||
|
||
}
|
||
|
||
ResononNirImager::~ResononNirImager()
|
||
{
|
||
if (buffer != nullptr)
|
||
{
|
||
std::cout << "释放堆上内存" << std::endl;
|
||
free(buffer);
|
||
free(dark);
|
||
free(white);
|
||
}
|
||
}
|
||
|
||
void ResononNirImager::reConnectImage()
|
||
{
|
||
disconnectImager();
|
||
connectImager();
|
||
}
|
||
|
||
double ResononNirImager::getFramerate()
|
||
{
|
||
return m_ResononNirImager.get_framerate();
|
||
}
|
||
|
||
double ResononNirImager::getIntegrationTime()
|
||
{
|
||
return m_ResononNirImager.get_integration_time();
|
||
}
|
||
|
||
double ResononNirImager::getGain()
|
||
{
|
||
//return m_ResononNirImager.get_gain();
|
||
return 0.0;//nir不支持gian
|
||
}
|
||
|
||
void ResononNirImager::setGain(const double gain)
|
||
{
|
||
//m_ResononNirImager.set_gain(gain);//nir不支持gian
|
||
}
|
||
|
||
void ResononNirImager::setFramerate(const double frames_per_second)
|
||
{
|
||
m_ResononNirImager.set_framerate(frames_per_second);
|
||
m_RgbImage->m_iFramerate = frames_per_second;
|
||
}
|
||
|
||
void ResononNirImager::setIntegrationTime(const double milliseconds)
|
||
{
|
||
m_ResononNirImager.set_integration_time(milliseconds);
|
||
}
|
||
|
||
int ResononNirImager::getStartBand()
|
||
{
|
||
return m_ResononNirImager.get_start_band();
|
||
}
|
||
|
||
int ResononNirImager::getEndBand()
|
||
{
|
||
return m_ResononNirImager.get_end_band();
|
||
}
|
||
|
||
void ResononNirImager::connectImager(const char* camera_sn)
|
||
{
|
||
m_ResononNirImager.connect();
|
||
}
|
||
|
||
void ResononNirImager::disconnectImager()
|
||
{
|
||
m_ResononNirImager.disconnect();
|
||
}
|
||
|
||
void ResononNirImager::imagerStartCollect()
|
||
{
|
||
m_ResononNirImager.start();
|
||
}
|
||
|
||
void ResononNirImager::imagerStopCollect()
|
||
{
|
||
m_ResononNirImager.stop();
|
||
}
|
||
|
||
unsigned short* ResononNirImager::getFrame(unsigned short* buffer)
|
||
{
|
||
m_ResononNirImager.get_frame(buffer);
|
||
|
||
return buffer;
|
||
}
|
||
|
||
void ResononNirImager::setSpectraBin(int new_spectral_bin)
|
||
{
|
||
|
||
}
|
||
|
||
double ResononNirImager::auto_exposure()
|
||
{
|
||
//第一步:先设置曝光时间为在当前帧率情况下最大
|
||
double x = 1 / getFramerate() * 1000;//获取最大毫秒曝光时间
|
||
reConnectImage();
|
||
setIntegrationTime(x);
|
||
|
||
//第二步:通过循环寻找最佳曝光时间
|
||
imagerStartCollect();
|
||
|
||
while (true)
|
||
{
|
||
getFrame(buffer);
|
||
if (GetMaxValue(buffer, m_FrameSize) >= 4095)
|
||
{
|
||
setIntegrationTime(getIntegrationTime() * 0.8);
|
||
std::cout << "自动曝光-----------" << std::endl;
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
reConnectImage();
|
||
//imagerStopCollect();
|
||
|
||
//std::cout << "自动曝光:" << getIntegrationTime() << std::endl;
|
||
|
||
return getIntegrationTime();
|
||
}
|
||
|
||
double ResononNirImager::getWavelengthAtBand(int band)
|
||
{
|
||
return m_ResononNirImager.get_wavelength_at_band(band);
|
||
}
|
||
|
||
int ResononNirImager::getBandCount()
|
||
{
|
||
return m_ResononNirImager.get_band_count();
|
||
}
|
||
|
||
int ResononNirImager::getSampleCount()
|
||
{
|
||
return m_ResononNirImager.get_sample_count();
|
||
}
|
||
|
||
void ResononNirImager::focus()
|
||
{
|
||
m_iFocusFrameCounter = 1;
|
||
//std::cout << "调焦-----------" << std::endl;
|
||
|
||
double tmpFrmerate = getFramerate();
|
||
double tmpIntegrationTime = getIntegrationTime();
|
||
|
||
|
||
setFramerate(5);
|
||
auto_exposure();
|
||
std::cout << "调焦获得的曝光时间为:" << getIntegrationTime() << std::endl;
|
||
|
||
reConnectImage();
|
||
imagerStartCollect();
|
||
|
||
//emit SpectralSignal(1);
|
||
m_bFocusControlState = true;
|
||
while (m_bFocusControlState)
|
||
{
|
||
getFrame(buffer);
|
||
//m_RgbImage->FillFocusGrayImage(buffer);
|
||
m_RgbImage->FillFocusGrayQImage(buffer);
|
||
|
||
emit SpectralSignal(1);
|
||
|
||
++m_iFocusFrameCounter;
|
||
}
|
||
emit SpectralSignal(0);
|
||
|
||
imagerStopCollect();
|
||
|
||
reConnectImage();
|
||
setIntegrationTime(tmpIntegrationTime);
|
||
|
||
setFramerate(tmpFrmerate);//必须要放在这里,如果不放这里,这行代码就要出错。。。。。。
|
||
}
|
||
|
||
void ResononNirImager::record_dark()
|
||
{
|
||
std::cout << "采集暗电流!!!!!!!!!" << std::endl;
|
||
reConnectImage();
|
||
imagerStartCollect();
|
||
|
||
unsigned int* dark_tmp = new unsigned int[m_FrameSize];
|
||
std::fill(dark_tmp, dark_tmp + m_FrameSize, 0);
|
||
|
||
int counter = 50;
|
||
for (size_t i = 0; i < counter; i++)
|
||
{
|
||
getFrame(dark);
|
||
|
||
for (size_t j = 0; j < m_FrameSize; j++)
|
||
{
|
||
dark_tmp[j] = dark[j] + dark_tmp[j];
|
||
}
|
||
}
|
||
|
||
for (size_t j = 0; j < m_FrameSize; j++)
|
||
{
|
||
dark[j] = (unsigned short)(dark_tmp[j] / counter);
|
||
}
|
||
delete[] dark_tmp;
|
||
|
||
imagerStopCollect();
|
||
|
||
m_HasDark = true;
|
||
|
||
emit RecordDarlFinishSignal();
|
||
}
|
||
|
||
void ResononNirImager::record_white()
|
||
{
|
||
std::cout << "采集白板!!!!!!!!!" << std::endl;
|
||
reConnectImage();
|
||
imagerStartCollect();
|
||
|
||
unsigned int* white_tmp = new unsigned int[m_FrameSize];
|
||
std::fill(white_tmp, white_tmp + m_FrameSize, 0);
|
||
|
||
int counter = 50;
|
||
for (size_t i = 0; i < counter; i++)
|
||
{
|
||
getFrame(white);
|
||
|
||
for (size_t j = 0; j < m_FrameSize; j++)
|
||
{
|
||
white_tmp[j] = white[j] + white_tmp[j];
|
||
}
|
||
}
|
||
|
||
for (size_t j = 0; j < m_FrameSize; j++)
|
||
{
|
||
white[j] = (unsigned short)(white_tmp[j] / counter);
|
||
}
|
||
delete[] white_tmp;
|
||
|
||
imagerStopCollect();
|
||
|
||
//白板扣暗电流
|
||
if (m_HasDark)
|
||
{
|
||
for (size_t i = 0; i < m_FrameSize; i++)
|
||
{
|
||
if (white[i] < dark[i])
|
||
{
|
||
white[i] = 0;
|
||
}
|
||
else
|
||
{
|
||
white[i] = white[i] - dark[i];
|
||
}
|
||
}
|
||
}
|
||
|
||
m_HasWhite = true;
|
||
|
||
emit RecordWhiteFinishSignal();
|
||
}
|
||
|
||
void ResononNirImager::start_record()
|
||
{
|
||
using namespace std;
|
||
|
||
//std::cout << "------------------------------------------------------" << std::endl;
|
||
|
||
m_iFrameCounter = 0;
|
||
m_RgbImage->m_iFrameCounter = 0;//设置填充rgb图像的第0行
|
||
m_bRecordControlState = true;
|
||
|
||
//判断内存buffer是否正常分配
|
||
if (buffer == 0)
|
||
{
|
||
std::cerr << "Error: memory could not be allocated for datacube";
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
|
||
m_FileName2Save2 = m_FileName2Save + "_" + std::to_string(m_FileSavedCounter) + ".bil";
|
||
FILE* m_fImage = fopen(m_FileName2Save2.c_str(), "w+b");
|
||
|
||
size_t x;
|
||
double pixelValueTmp;
|
||
|
||
string timesFile = removeFileExtension(m_FileName2Save2) + ".times";
|
||
FILE* hTimesFile = fopen(timesFile.c_str(), "w+");
|
||
|
||
reConnectImage();//nir第二次采集时需要重新连接相机,否则函数imagerStartCollect()会报错。。。。。。
|
||
imagerStartCollect();
|
||
while (m_bRecordControlState)
|
||
{
|
||
m_iFrameCounter++;
|
||
|
||
getFrame(buffer);
|
||
long long timeOs = getNanosecondsSinceMidnight();
|
||
//qDebug() << "time ns-------------------: " << timeOs;
|
||
|
||
//减去暗电流,应为buffer和dark都是unsigned short,所以当dark>buffer时,buffer-dark=65535
|
||
if (m_HasDark)
|
||
{
|
||
for (size_t i = 0; i < m_FrameSize; i++)
|
||
{
|
||
if (buffer[i] < dark[i])
|
||
{
|
||
buffer[i] = 0;
|
||
}
|
||
else
|
||
{
|
||
buffer[i] = buffer[i] - dark[i];
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
|
||
//转反射率
|
||
if (m_HasWhite)
|
||
{
|
||
for (size_t i = 0; i < m_FrameSize; i++)
|
||
{
|
||
//处理除数(白板)为0的情况
|
||
if (white[i] != 0)
|
||
{
|
||
pixelValueTmp = buffer[i];
|
||
buffer[i] = (pixelValueTmp / white[i]) * 10000;
|
||
}
|
||
else
|
||
{
|
||
buffer[i] = 0;
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
x = fwrite(buffer, 2, m_FrameSize, m_fImage);
|
||
fprintf(hTimesFile, "%lld\n", timeOs);
|
||
|
||
//将rgb波段提取出来,以便在界面中显示
|
||
m_RgbImage->FillRgbImage(buffer);//??????????????????????????????????????????????????????????????????????????????????????????????????????
|
||
|
||
//std::cout << "第" << m_iFrameCounter << "帧写了" << x << "个unsigned short。" << std::endl;
|
||
|
||
//每隔1s进行一次界面图形绘制
|
||
if (m_iFrameCounter % (int)getFramerate() == 0)
|
||
{
|
||
emit PlotSignal();
|
||
}
|
||
|
||
if (m_iFrameCounter >= m_iFrameNumber)
|
||
{
|
||
break;
|
||
//qDebug() << "相机停止采集:帧数限制到达。";
|
||
}
|
||
|
||
}
|
||
imagerStopCollect();
|
||
|
||
m_bRecordControlState = false;
|
||
WriteHdr();
|
||
m_FileSavedCounter++;
|
||
|
||
//在最后一次画图前需要进行一次拉伸
|
||
//m_RgbImage
|
||
emit PlotSignal();//采集完成后进行一次画图,以防采集帧数不是帧率的倍数时,画图不全
|
||
|
||
if (m_iFrameCounter >= m_iFrameNumber)
|
||
{
|
||
emit RecordFinishedSignal_WhenFrameNumberMeet();
|
||
}
|
||
else
|
||
{
|
||
emit RecordFinishedSignal_WhenFrameNumberNotMeet();
|
||
}
|
||
|
||
//QThread::msleep(1001);
|
||
fclose(m_fImage);
|
||
fclose(hTimesFile);
|
||
}
|
||
|
||
void ResononNirImager::WriteHdr()
|
||
{
|
||
//write an ENVI compatible header file
|
||
using namespace std;
|
||
|
||
string hdrPath = removeFileExtension(m_FileName2Save2) + ".hdr";
|
||
|
||
std::ofstream outfile(hdrPath.c_str());
|
||
outfile << "ENVI\n";
|
||
outfile << "interleave = bil\n";
|
||
outfile << "data type = 12\n";
|
||
outfile << "bit depth = 12\n";
|
||
outfile << "samples = " << getSampleCount() << "\n";
|
||
outfile << "bands = " << getBandCount() << "\n";
|
||
outfile << "lines = " << m_iFrameCounter << "\n";
|
||
outfile << "framerate = " << getFramerate() << "\n";
|
||
outfile << "shutter = " << getIntegrationTime() << "\n";
|
||
outfile << "gain = " << getGain() << "\n";
|
||
outfile << "wavelength = {";
|
||
outfile << std::setprecision(5);
|
||
|
||
int num_bands = getBandCount();
|
||
for (int i = 0; i < num_bands - 1; i++)
|
||
{
|
||
outfile << getWavelengthAtBand(i) << ", ";
|
||
}
|
||
outfile << getWavelengthAtBand(num_bands - 1) << "}\n";
|
||
outfile.close();
|
||
}
|