544 lines
12 KiB
C++
544 lines
12 KiB
C++
#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;
|
||
}
|