#include "ImagerOperationBase.h" #include 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(); double exposureTime = getIntegrationTime(); emit autoExposureSignal(exposureTime); //std::cout << "自动曝光:" << exposureTime << std::endl; return exposureTime; } 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() { QObject* obj = sender(); if (obj) { qDebug() << "ImagerOperationBase::start_record, sender name:" << obj->objectName(); } else { qDebug() << "ImagerOperationBase::start_record, sender is null"; } 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, "visibleLight"); 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(); //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, "%ll\n", timeOs); //将rgb波段提取出来,以便在界面中显示 m_RgbImage->FillRgbImage(buffer, 121, 79, 40);//?????????????????????????????????????????????????????????????????????????????????????????????????????? //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::updateRecordingFileInfo(const QString& filePath, const QString& baseName, int frameNumber) { m_FileName2Save = (filePath + QDir::separator() + baseName).toStdString(); m_FileSavedCounter = 0; setFrameNumber(frameNumber); } 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; }