Files
HPPA/HPPA/ImagerOperationBase.cpp
2026-03-03 17:22:03 +08:00

544 lines
12 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 "ImagerOperationBase.h"
ImagerOperationBase::ImagerOperationBase()
{
m_iFrameCounter = 1;
m_bRecordControlState = true;
m_FileName2Save = "tmp_image";
m_FileSavedCounter = 0;
m_RgbImage = new CImage();
buffer = nullptr;
dark = nullptr;
white = nullptr;
m_HasDark = false;
m_HasWhite = false;
m_bFocusControlState = false;
}
ImagerOperationBase::~ImagerOperationBase()
{
}
void ImagerOperationBase::connect_imager(int frameNumber)
{
connectImager();
setIntegrationTime(1);
setFramerate(30.0);
//set_gain(0);
//m_ResononNirImager.set_spectral_bin(2);
set_buffer();
m_RgbImage->SetRgbImageWidthAndHeight(getBandCount(), getSampleCount(), frameNumber);
m_iFrameNumber = frameNumber;
emit testImagerStatus();
//std::cout << "------------------------------------------------------" << std::endl;
}
double ImagerOperationBase::auto_exposure()
{
//第一步:先设置曝光时间为在当前帧率情况下最大
double x = 1 / getFramerate() * 1000;//获取最大毫秒曝光时间
setIntegrationTime(x);
//第二步:通过循环寻找最佳曝光时间
imagerStartCollect();
while (true)
{
getFrame(buffer);
if (GetMaxValue(buffer, m_FrameSize) >= 4094)
{
setIntegrationTime(getIntegrationTime() * 0.95);
std::cout << "自动曝光-----------" << std::endl;
}
else
{
break;
}
}
imagerStopCollect();
//std::cout << "自动曝光:" << getIntegrationTime() << std::endl;
return getIntegrationTime();
}
void ImagerOperationBase::focus()
{
m_iFocusFramesNumber = 0;
m_iFocusFrameCounter = 1;
//std::cout << "调焦-----------" << std::endl;
double tmpFrmerate = getFramerate();
double tmpIntegrationTime = getIntegrationTime();
setFramerate(5);
auto_exposure();
std::cout << "调焦获得的曝光时间为:" << getIntegrationTime() << std::endl;
int iWidth, iHeight;
GetFrameSize(iWidth, iHeight);
unsigned short* tmp = new unsigned short[m_FrameSize];
imagerStartCollect();
//emit SpectralSignal(1);
m_bFocusControlState = true;
while (m_bFocusControlState)
{
////多帧平均,减弱单帧跳动
//memset((void*)buffer, 0, m_FrameSize * sizeof(unsigned short));
//int fn = 5;
//for (int i = 0; i < fn; i++)
//{
// getFrame(tmp);
// for (int j = 0; j < m_FrameSize; j++)
// {
// buffer[j] += tmp[j];
// }
//}
//for (int j = 0; j < m_FrameSize; j++)
//{
// buffer[j] += buffer[j] / fn;
//}
getFrame(buffer);
//m_RgbImage->FillFocusGrayImage(buffer);
m_RgbImage->FillFocusGrayQImage(buffer);
double focusIndex = calcFocusIndexSobelPrivate(buffer);
emit FocusIndexSobelSignal(focusIndex);
std::cout << "focusIndex" << focusIndex << std::endl;
emit SpectralSignal(1);
++m_iFocusFrameCounter;
}
emit SpectralSignal(0);
imagerStopCollect();
delete[] tmp;
setFramerate(tmpFrmerate);
setIntegrationTime(tmpIntegrationTime);
}
void ImagerOperationBase::record_dark()
{
std::cout << "采集暗电流!!!!!!!!!" << std::endl;
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 ImagerOperationBase::record_white()
{
std::cout << "采集白板!!!!!!!!!" << std::endl;
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 ImagerOperationBase::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);
}
// 在开始采集时仅发出文件信息UI 层自行创建 MapLayer 并管理生命周期
// prepare file name that will be used for saving
m_FileName2Save2 = m_FileName2Save + "_" + std::to_string(m_FileSavedCounter) + ".bil";
QString baseName = QString::fromStdString(getFileNameFromPath(m_FileName2Save2));
QString filePath = QString::fromStdString(m_FileName2Save2);
emit LayerFileCreated(baseName, filePath, m_FileSavedCounter);
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+");
imagerStartCollect();
while (m_bRecordControlState)
{
m_iFrameCounter++;
getFrame(buffer);
long long timeOs = getNanosecondsSinceMidnight();
//减去暗电流应为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, "%d\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(m_FileSavedCounter, m_iFrameCounter, filePath);
}
if (m_iFrameCounter >= m_iFrameNumber)
{
break;
}
}
imagerStopCollect();
//在最后一次画图前需要进行一次拉伸
//m_RgbImage
emit PlotSignal(m_FileSavedCounter, -1, filePath);
m_bRecordControlState = false;
WriteHdr();
// 发射 ImageFileSaved 信号,通知 UI 层把该文件加入图层管理器
// m_FileName2Save2 保存了本次写入的 .bil 文件名(例如 "tmp_image_0.bil"
emit ImageFileSaved(QString::fromStdString(m_FileName2Save2), m_FileSavedCounter);
m_FileSavedCounter++;
if (m_iFrameCounter >= m_iFrameNumber)
{
emit RecordFinishedSignal_WhenFrameNumberMeet();
}
else
{
emit RecordFinishedSignal_WhenFrameNumberNotMeet();
}
//QThread::msleep(1001);
fclose(m_fImage);
fclose(hTimesFile);
}
void ImagerOperationBase::setFrameNumber(int FrameNumber)
{
m_iFrameNumber = FrameNumber;
m_RgbImage->SetRgbImageWidthAndHeight(getBandCount(), getSampleCount(), FrameNumber);
}
void ImagerOperationBase::setFileName2Save(string FileName)
{
m_FileName2Save = FileName;
m_FileSavedCounter = 0;
}
void ImagerOperationBase::setFocusControlState(bool FocusControlState)
{
m_bFocusControlState = FocusControlState;
}
int ImagerOperationBase::GetFrameSize(int& iWidth, int& iHeight)
{
/*using namespace GENAPI_NAMESPACE;
using namespace std;
INodeMap& nodemap = m_phCamera->GetNodeMap();
iWidth = (int)CIntegerPtr(nodemap.GetNode("Width"))->GetValue();
iHeight = (int)CIntegerPtr(nodemap.GetNode("Height"))->GetValue();*/
iWidth = getSampleCount();
iHeight = getBandCount();
return 0;
}
void ImagerOperationBase::getFocusIndexSobel()
{
imagerStartCollect();
getFrame(buffer);
imagerStopCollect();
double focusIndex = calcFocusIndexSobelPrivate(buffer);
emit FocusIndexSobelSignal(focusIndex);
}
double ImagerOperationBase::calcFocusIndexSobelPrivate(void* pvData)
{
int iSelection = 0;
int iWidth, iHeight;
GetFrameSize(iWidth, iHeight);
unsigned short* psData;
psData = (unsigned short*)pvData;
cv::Mat gray(iHeight, iWidth, CV_16UC1, psData);//经验证gray.data的数据和psData一样
/*string rgbFilePathNoStrech = "E:\\hppa\\delete\\focusImg_";
string tmp1 = std::to_string(m_iFocusFramesNumber);
string tmp2 = ".png";*/
string rgbFilePathNoStrech = "E:\\hppa\\delete\\focusImg_" + std::to_string(m_iFocusFramesNumber) + ".png";
//cv::imwrite(rgbFilePathNoStrech, gray);
m_iFocusFramesNumber++;
//进行滤波
//cv::Mat outputImage;
//cv::Size kernelSize(5, 5);
//double sigmaX = 1.5;
//cv::GaussianBlur(gray, outputImage, kernelSize, sigmaX);
cv::Mat outputImage = gray;
cv::Mat gradX, gradY, absGradX, absGradY;
cv::Sobel(outputImage, gradX, CV_32F, 1, 0);//如果参数为CV_16S则函数cv::magnitude报错
cv::Sobel(outputImage, gradY, CV_32F, 0, 1);
cv::convertScaleAbs(gradX, absGradX);
cv::convertScaleAbs(gradY, absGradY);
cv::Mat grad;
cv::addWeighted(absGradX, 0.5, absGradY, 0.5, 0, grad);
cv::Mat magnitude, direction;
cv::magnitude(gradX, gradY, magnitude);//
cv::phase(gradX, gradY, direction, true); // true表示返回角度而非弧度
return cv::mean(magnitude)[0];
}
CImage* ImagerOperationBase::getRgbImage() const
{
return m_RgbImage;
}
cv::Mat* ImagerOperationBase::getMatRgbImage() const
{
return m_RgbImage->m_matRgbImage;
}
cv::Mat* ImagerOperationBase::getMatFocusGrayImage() const
{
return m_RgbImage->m_matFocusGrayImage;
}
QImage ImagerOperationBase::getQImageFocusGrayImage() const
{
return *m_RgbImage->m_qimageFocusGrayImage;
}
bool ImagerOperationBase::getRecordControlState() const
{
return m_bRecordControlState;
}
void ImagerOperationBase::setRecordControlState(bool RecordControlState)
{
m_bRecordControlState = RecordControlState;
}
void ImagerOperationBase::stop_record()
{
m_bRecordControlState = false;
}
int ImagerOperationBase::getFrameCounter() const
{
return m_iFrameCounter;
}
int ImagerOperationBase::getFocusFrameCounter() const
{
return m_iFocusFrameCounter;
}
void ImagerOperationBase::set_buffer()
{
//如果
if (buffer != nullptr)
{
std::cout << "释放堆上内存" << std::endl;
free(buffer);
}
m_FrameSize = getBandCount() * getSampleCount();
//std::cout << "m_FrameSize大小为" << m_FrameSize << std::endl;
buffer = new unsigned short[m_FrameSize];
dark = new unsigned short[m_FrameSize];
white = new unsigned short[m_FrameSize];
std::cout << "buffer内存地址" << buffer << std::endl;
std::cout << "dark内存地址" << dark << std::endl;
std::cout << "white内存地址" << white << std::endl;
}
void ImagerOperationBase::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 << "byte order = 0\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 start = getStartBand();
int end = getEndBand();
for (int i = start; i < end - 1; i++)
{
outfile << getWavelengthAtBand(i) << ", ";
}
outfile << getWavelengthAtBand(end - 1) << "}\n";
outfile.close();
}
unsigned short ImagerOperationBase::GetMaxValue(unsigned short* dark, int number)
{
unsigned short max = 0;
for (size_t i = 0; i < number; i++)
{
if (dark[i] > max)
{
max = dark[i];
}
}
//std::cout << "本帧最大值为" << max << std::endl;
return max;
}