Files
HPPA/HPPA/ResononNirImager.cpp
tangchao0503 f32ade7487 1、添加仅采集影像,马达不运动的功能,可用于机械臂和影像采集测试;
2、使用 QSettings 记录 Action 的 isChecked 状态,并在打开软件时恢复;
2025-04-11 15:48:27 +08:00

419 lines
8.4 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 "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();
}