From 6469bff15db66b99680b55b9d4900934679feece Mon Sep 17 00:00:00 2001 From: tangchao0503 <735056338@qq.com> Date: Wed, 11 Dec 2024 13:50:03 +0800 Subject: [PATCH] =?UTF-8?q?fix=20&=20add=201=E3=80=81=E5=9C=A8=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E4=B8=8A=E5=AE=9E=E7=8E=B0=E9=80=89=E6=8B=A9=E7=9B=B8?= =?UTF-8?q?=E6=9C=BA=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=8A=9F=E8=83=BD=EF=BC=9B?= =?UTF-8?q?=202=E3=80=81=E5=88=9B=E5=BB=BA=E4=BA=86=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=85=89=E8=B0=B1=E4=BB=AA=E6=93=8D=E4=BD=9C=E7=9A=84=E7=BA=AF?= =?UTF-8?q?=E8=99=9A=E5=9F=BA=E7=B1=BB=EF=BC=88ImagerOperationBase?= =?UTF-8?q?=EF=BC=89=E5=B9=B6=E5=AE=9E=E7=8E=B0=E4=BA=86=E5=A4=A7=E9=83=A8?= =?UTF-8?q?=E5=88=86=E7=9A=84=E6=93=8D=E4=BD=9C=EF=BC=8C=E5=85=B7=E4=BD=93?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=85=89=E8=B0=B1=E4=BB=AA=E5=BA=94?= =?UTF-8?q?=E7=BB=A7=E6=89=BF=E6=AD=A4=E7=B1=BB=E5=B9=B6=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=BA=AF=E8=99=9A=E5=87=BD=E6=95=B0=EF=BC=9B=203=E3=80=81?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=20resonon=20=E7=9A=84=20nir=20320?= =?UTF-8?q?=20=E7=9B=B8=E6=9C=BA=EF=BC=8C=E4=BF=AE=E6=94=B9=20resonon=20?= =?UTF-8?q?=E7=9A=84=20pica=20l=20=E7=9B=B8=E6=9C=BA=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=9A=E7=BB=A7=E6=89=BF=20ImagerOperationBase?= =?UTF-8?q?=EF=BC=9B=204=E3=80=81=E9=87=8D=E6=9E=84=E7=B1=BB=20QMotorDoubl?= =?UTF-8?q?eSlider=EF=BC=8C=E6=8F=90=E9=AB=98=E5=85=B6=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E6=89=80=E6=9C=89=E9=A9=AC=E8=BE=BE=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84=20slider=20=E9=83=BD=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=AD=A4=E7=B1=BB=EF=BC=9B=205=E3=80=81=E9=80=82=E9=85=8D=20re?= =?UTF-8?q?sonon=20nir=20320=20=E6=98=BE=E5=BE=AE=E9=95=9C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=9A=84=202=20=E8=BD=B4=E7=BA=BF=E6=80=A7=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=EF=BC=8C=E6=9C=89=E4=BA=9B=E7=89=B9=E6=AE=8A=E7=9A=84?= =?UTF-8?q?=E9=A9=AC=E8=BE=BE=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE=EF=BC=88?= =?UTF-8?q?setMotorParamMicroscope=20=E5=87=BD=E6=95=B0=EF=BC=89=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E4=BA=86=20nir=20=E7=9A=84=E7=9B=B8=E6=9C=BA=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=8F=82=E6=95=B0=EF=BC=9B=206=E3=80=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=9A=E5=B0=86=E7=BA=BF=E6=80=A7=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E7=9A=84=E9=87=8F=E7=A8=8B=E4=BF=A1=E6=81=AF=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8cfg=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=AF=BB=E5=86=99=E7=B1=BB=E6=9D=A5=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E6=AD=A4=E9=87=8F=E7=A8=8B=E4=BF=A1=E6=81=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HPPA.sln | 2 +- HPPA/HPPA.cpp | 293 +++++++++++++++--------- HPPA/HPPA.h | 17 +- HPPA/HPPA.ui | 180 ++++++++++++--- HPPA/HPPA.vcxproj | 20 +- HPPA/HPPA.vcxproj.filters | 24 +- HPPA/ImagerOperationBase.cpp | 399 ++++++++++++++++++++++++++++++++ HPPA/ImagerOperationBase.h | 102 +++++++++ HPPA/QMotorDoubleSlider.cpp | 19 +- HPPA/QMotorDoubleSlider.h | 11 +- HPPA/QYMotorDoubleSlider.cpp | 101 -------- HPPA/QYMotorDoubleSlider.h | 41 ---- HPPA/ResononNirImager.cpp | 338 +++++++++++++++++++++++++++ HPPA/ResononNirImager.h | 50 ++++ HPPA/about.ui | 2 +- HPPA/focusWindow.cpp | 10 +- HPPA/focusWindow.h | 5 +- HPPA/hppaConfigFile.cpp | 45 +++- HPPA/hppaConfigFile.h | 8 +- HPPA/imageProcessor.cpp | 2 +- HPPA/resononImager.cpp | 430 ++++------------------------------- HPPA/resononImager.h | 87 ++----- HPPA/utility_tc.cpp | 123 ++++++++++ HPPA/utility_tc.h | 23 ++ 24 files changed, 1544 insertions(+), 788 deletions(-) create mode 100644 HPPA/ImagerOperationBase.cpp create mode 100644 HPPA/ImagerOperationBase.h delete mode 100644 HPPA/QYMotorDoubleSlider.cpp delete mode 100644 HPPA/QYMotorDoubleSlider.h create mode 100644 HPPA/ResononNirImager.cpp create mode 100644 HPPA/ResononNirImager.h create mode 100644 HPPA/utility_tc.cpp create mode 100644 HPPA/utility_tc.h diff --git a/HPPA.sln b/HPPA.sln index 45ff640..398ac97 100644 --- a/HPPA.sln +++ b/HPPA.sln @@ -8,7 +8,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HPPA", "HPPA\HPPA.vcxproj", {B12702AD-ABFB-343A-A199-8E24837244A3} = {B12702AD-ABFB-343A-A199-8E24837244A3} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vincecontrol", "..\..\cpp_project_vs2019\vincecontrol\vincecontrol\vincecontrol.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vincecontrol", "vincecontrol\vincecontrol.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index 87cf782..5def0de 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -15,6 +15,37 @@ HPPA::HPPA(QWidget *parent) { ui.setupUi(this); + //配置文件:如果没有,就创建配置文件 + string HPPACfgFile = getPathofEXE() + "\\HPPA.cfg"; + configfile.setConfigfilePath(HPPACfgFile); + if (!configfile.isConfigfileExist()) + { + configfile.createConfigFile(); + qDebug() << "create: " << QString::fromStdString(HPPACfgFile); + } + configfile.parseConfigfile(); + qDebug() << "exist: " << QString::fromStdString(HPPACfgFile); + + /*int max, min; + configfile.getPositionRestriction(max, min); + + string sn; + configfile.getSN(sn); + + int coarse, fine; + configfile.getTuningStepSize(coarse, fine); + float fa, fb; + configfile.getFitParams(fa, fb); + int max_FocusRange, min_FocusRange; + configfile.getAutoFocusRange(max_FocusRange, min_FocusRange); + + float StepAnglemar_x, Lead_x, ScaleFactor_x; + int SubdivisionMultiples_x; + configfile.getXMotorParm(StepAnglemar_x, Lead_x, SubdivisionMultiples_x, ScaleFactor_x); + float StepAnglemar_y, Lead_y, ScaleFactor_y; + int SubdivisionMultiples_y; + configfile.getYMotorParm(StepAnglemar_y, Lead_y, SubdivisionMultiples_y, ScaleFactor_y);*/ + //状态栏 xmotor_state_label1 = new QLabel(); ymotor_state_label1 = new QLabel(); @@ -24,9 +55,6 @@ HPPA::HPPA(QWidget *parent) ui.statusBar->addPermanentWidget(ymotor_state_label1); - - - connect(this->ui.action_exit, SIGNAL(triggered()), this, SLOT(onExit())); //ui.cam_label->setScaledContents(true); @@ -108,7 +136,7 @@ HPPA::HPPA(QWidget *parent) m_xMotor = nullptr; m_yMotor = nullptr; - newMotor(); + //m_TestXmotorStausThread = new MotorWorkerThread(m_xMotor); @@ -136,6 +164,15 @@ HPPA::HPPA(QWidget *parent) QRegExp rx("\\d{0,3}[1-9]$"); ui.xmotor_speed_lineEdit->setValidator(new QRegExpValidator(rx)); + //读取配置文件 + float lead;//导程 + float stepAnglemar;//步距角 + float scaleFactor;//因机械装置的原因引入的缩放因子 + int subdivisionMultiples;//细分数 + float maxRange; + configfile.getXMotorParm(stepAnglemar, lead, subdivisionMultiples, scaleFactor, maxRange); + + ui.xmotor_speed_slider->setMultiplier(lead, stepAnglemar, scaleFactor, subdivisionMultiples); ui.xmotor_speed_slider->setRange(0, 3);//5.2734375cm/s=10000脉冲 ui.xmotor_speed_slider->setValue(1); connect(this->ui.xmotor_speed_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnXmotorSpeedLineeditEditingFinished())); @@ -145,14 +182,14 @@ HPPA::HPPA(QWidget *parent) connect(this->ui.xmotor_location_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnXmotorLocationLineeditEditingFinished())); connect(this->ui.xmotor_location_slider, SIGNAL(valueChanged(double)), this, SLOT(OnXmotorLocationSliderChanged(double))); connect(this->ui.xmotor_location_slider, SIGNAL(sliderReleased()), this, SLOT(OnXmotorLocationSliderReleased())); + ui.xmotor_location_slider->setMultiplier(lead, stepAnglemar, scaleFactor, subdivisionMultiples); ui.xmotor_location_slider->setValue(0); - - - + configfile.getYMotorParm(stepAnglemar, lead, subdivisionMultiples, scaleFactor, maxRange); connect(this->ui.ymotor_location_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnYmotorLocationLineeditEditingFinished())); connect(this->ui.ymotor_location_slider, SIGNAL(valueChanged(double)), this, SLOT(OnYmotorLocationSliderChanged(double))); connect(this->ui.ymotor_location_slider, SIGNAL(sliderReleased()), this, SLOT(OnYmotorLocationSliderReleased())); + ui.ymotor_location_slider->setMultiplier(lead, stepAnglemar, scaleFactor, subdivisionMultiples); ui.ymotor_location_slider->setValue(0); @@ -233,38 +270,7 @@ HPPA::HPPA(QWidget *parent) // connect(this->ui.action_about, SIGNAL(triggered()), this, SLOT(onAbout())); - //配置文件:如果没有,就创建配置文件 - string HPPACfgFile = getPathofEXE() + "\\HPPA.cfg"; - - Configfile configfile; - configfile.setConfigfilePath(HPPACfgFile); - if (!configfile.isConfigfileExist()) - { - configfile.createConfigFile(); - qDebug() << "create: " << QString::fromStdString(HPPACfgFile); - } - configfile.parseConfigfile(); - qDebug() << "exist: " << QString::fromStdString(HPPACfgFile); - - /*int max, min; - configfile.getPositionRestriction(max, min); - - string sn; - configfile.getSN(sn); - - int coarse, fine; - configfile.getTuningStepSize(coarse, fine); - float fa, fb; - configfile.getFitParams(fa, fb); - int max_FocusRange, min_FocusRange; - configfile.getAutoFocusRange(max_FocusRange, min_FocusRange); - - float StepAnglemar_x, Lead_x, ScaleFactor_x; - int SubdivisionMultiples_x; - configfile.getXMotorParm(StepAnglemar_x, Lead_x, SubdivisionMultiples_x, ScaleFactor_x); - float StepAnglemar_y, Lead_y, ScaleFactor_y; - int SubdivisionMultiples_y; - configfile.getYMotorParm(StepAnglemar_y, Lead_y, SubdivisionMultiples_y, ScaleFactor_y);*/ + // connect(ui.objective_table1_up_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable1Up_btn())); @@ -274,12 +280,36 @@ HPPA::HPPA(QWidget *parent) connect(ui.objective_table2_up_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable2Up_btn())); connect(ui.objective_table2_down_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable2Down_btn())); connect(ui.objective_table2_stop_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable2Stop_btn())); + + createActionGroups(); + connect(mImagerGroup, &QActionGroup::triggered, this, &HPPA::selectingImager); +} + +void HPPA::createActionGroups() +{ + // Imager Tool Group + mImagerGroup = new QActionGroup(this); + mImagerGroup->addAction(ui.mActionPica_L); + mImagerGroup->addAction(ui.mActionPika_XC2); + mImagerGroup->addAction(ui.mActionCorning_410); + mImagerGroup->addAction(ui.mActionPica_NIR); + + ui.mActionPica_NIR->setChecked(true); + imagerSelected = ui.mActionPica_NIR->objectName(); +} + +void HPPA::selectingImager(QAction* selectedAction) +{ + imagerSelected = selectedAction->objectName(); } HPPA::~HPPA() { if (m_Imager != nullptr) - m_Imager->~ResononImager();//释放资源 + { + //m_Imager->~ResononNirImager();//释放资源 + delete m_Imager; + } if (m_xMotor != nullptr && m_yMotor != nullptr) { @@ -296,7 +326,7 @@ HPPA::~HPPA() void HPPA::CalculateIntegratioinTimeRange() { - double range = 1 / m_Imager->get_framerate() * 1000;//毫秒 + double range = 1 / m_Imager->getFramerate() * 1000;//毫秒 ui.IntegratioinTimeSlider->blockSignals(true);//因为setMaximum会触发valueChanged信号,所以调用setMaximum前需要阻断信号 ui.IntegratioinTimeSlider->setMaximum(range); @@ -544,7 +574,7 @@ void HPPA::onActionOpenDirectory() void HPPA::OnFramerateLineeditEditingFinished() { std::cout << "Lineedit设置帧率------------------------------------------" << std::endl; - m_Imager->set_framerate(this->ui.framerate_lineEdit->text().toDouble()); + m_Imager->setFramerate(this->ui.framerate_lineEdit->text().toDouble()); ui.FramerateSlider->setValue(ui.framerate_lineEdit->text().toDouble()); CalculateIntegratioinTimeRange(); @@ -553,7 +583,7 @@ void HPPA::OnFramerateLineeditEditingFinished() void HPPA::OnFramerateSliderChanged(double framerate) { std::cout << "Slider设置帧率------------------------------------------" << std::endl; - m_Imager->set_framerate(this->ui.framerate_lineEdit->text().toDouble()); + m_Imager->setFramerate(this->ui.framerate_lineEdit->text().toDouble()); ui.framerate_lineEdit->setText(QString::number(framerate)); CalculateIntegratioinTimeRange(); @@ -562,26 +592,26 @@ void HPPA::OnFramerateSliderChanged(double framerate) void HPPA::OnIntegratioinTimeEditingFinished() { std::cout << "Lineedit设置积分时间------------------------------------------" << std::endl; - m_Imager->set_integration_time(this->ui.integratioin_time_lineEdit->text().toDouble()); + m_Imager->setIntegrationTime(this->ui.integratioin_time_lineEdit->text().toDouble()); ui.IntegratioinTimeSlider->setValue(ui.integratioin_time_lineEdit->text().toDouble()); } void HPPA::OnIntegratioinTimeSliderChanged(double IntegratioinTime) { std::cout << "Slider设置积分时间------------------------------------------" << std::endl; - m_Imager->set_integration_time(IntegratioinTime); + m_Imager->setIntegrationTime(IntegratioinTime); ui.integratioin_time_lineEdit->setText(QString::number(IntegratioinTime)); } void HPPA::OnGainEditingFinished() { - m_Imager->set_gain(this->ui.gain_lineEdit->text().toDouble()); + m_Imager->setGain(this->ui.gain_lineEdit->text().toDouble()); ui.GainSlider->setValue(ui.gain_lineEdit->text().toDouble()); } void HPPA::OnGainSliderChanged(double Gain) { - m_Imager->set_gain(this->ui.gain_lineEdit->text().toDouble()); + m_Imager->setGain(this->ui.gain_lineEdit->text().toDouble()); ui.gain_lineEdit->setText(QString::number(Gain)); } @@ -603,7 +633,7 @@ void HPPA::onLeftMouseButtonPressed(int x, int y) ImageReaderWriter *ImageReader = new ImageReaderWriter(imgPath.c_str()); - if (x < 0 || x>899 || y<0 || y>ImageReader->getyCount() - 1) + if (x < 0 || x>ImageReader->getXCount() || y<0 || y>ImageReader->getyCount() - 1) { return; } @@ -654,6 +684,13 @@ void HPPA::timerEvent(QTimerEvent *event) if (m_xMotor == nullptr || m_yMotor == nullptr) { qDebug() << "Motor pointer is null!!!!!"; + + xmotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}"); + SetXMotorWidgetEnable(false); + + ymotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}"); + SetYMotorWidgetEnable(false); + return; } @@ -727,6 +764,7 @@ void HPPA::onxMotorLeft() m_xMotor->EnableMotro(); m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor); + //m_xMotor->SettingSpeed(ui.xmotor_speed_lineEdit->text().toLong()); m_xMotor->MoveMotar(false); } @@ -740,6 +778,7 @@ void HPPA::onxMotorRight() m_xMotor->EnableMotro(); m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor); + //m_xMotor->SettingSpeed(ui.xmotor_speed_lineEdit->text().toLong()); m_xMotor->MoveMotar(true); } @@ -766,6 +805,7 @@ void HPPA::onyMotorForward() m_yMotor->EnableMotro(); m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor); + //m_yMotor->SettingSpeed(ui.xmotor_speed_lineEdit->text().toLong()); m_yMotor->MoveMotar(true); } @@ -781,6 +821,7 @@ void HPPA::onyMotorBackward() m_yMotor->EnableMotro(); m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor); + //m_yMotor->SettingSpeed(ui.xmotor_speed_lineEdit->text().toLong()); m_yMotor->MoveMotar(false); } @@ -846,8 +887,8 @@ void HPPA::SetXMotorWidgetEnable(bool enable) ui.test_range_btn->setEnabled(enable); ui.motor_reset_btn->setEnabled(enable); - //ui.xmotor_left_btn->setEnabled(enable); - //ui.xmotor_right_btn->setEnabled(enable); + ui.xmotor_left_btn->setEnabled(enable); + ui.xmotor_right_btn->setEnabled(enable); ui.xmotor_speed_lineEdit->setEnabled(enable); ui.xmotor_speed_slider->setEnabled(enable); ui.xmotor_location_lineEdit->setEnabled(enable); @@ -859,8 +900,8 @@ void HPPA::SetYMotorWidgetEnable(bool enable) ui.test_range_btn->setEnabled(enable); ui.motor_reset_btn->setEnabled(enable); - //ui.ymotor_forward_btn->setEnabled(enable); - //ui.ymotor_backward_btn->setEnabled(enable); + ui.ymotor_forward_btn->setEnabled(enable); + ui.ymotor_backward_btn->setEnabled(enable); ui.ymotor_location_lineEdit->setEnabled(enable); ui.ymotor_location_slider->setEnabled(enable); } @@ -870,28 +911,17 @@ void HPPA::setMotorRange() try { //将x马达量程记录到文件,以便后面使用 → 不用每次都测试量程,这样很浪费时间 + float xMotorRange; + float yMotorRange; - FileOperation * fileOperation = new FileOperation(); - string directory = fileOperation->getDirectoryOfExe(); - string xMotorRangeFilePath = directory + "\\xMotorRange"; - string yMotorRangeFilePath = directory + "\\yMotorRange"; + float lead;//导程 + float stepAnglemar;//步距角 + float scaleFactor;//因机械装置的原因引入的缩放因子 + int subdivisionMultiples;//细分数 + configfile.getXMotorParm(stepAnglemar, lead, subdivisionMultiples, scaleFactor, xMotorRange); + configfile.getYMotorParm(stepAnglemar, lead, subdivisionMultiples, scaleFactor, yMotorRange); - FILE * xMotorRangeFile = fopen(xMotorRangeFilePath.c_str(), "r+b"); - FILE * yMotorRangeFile = fopen(yMotorRangeFilePath.c_str(), "r+b"); - - - //FILE * xMotorRangeFile = fopen("xMotorRange", "r+b"); - //FILE * yMotorRangeFile = fopen("yMotorRange", "r+b"); - - double xMotorRange; - double yMotorRange; - - fread(&xMotorRange, sizeof(double), 1, xMotorRangeFile); - fread(&yMotorRange, sizeof(double), 1, yMotorRangeFile); - - fclose(xMotorRangeFile); - fclose(yMotorRangeFile); //std::cout << "xMotorRange:" << xMotorRange << std::endl; //std::cout << "yMotorRange:" << yMotorRange << std::endl; @@ -1100,10 +1130,10 @@ void HPPA::ontimerTestRangeOfxMotor() { if (isMotorConnected(m_xMotor)) { - std::cout << "x马达有问题+++++++++++++++++++++++++++++++++++++++++++" << std::endl; + qDebug() << "x TestRangeOfxMotor: x motor is bad+++++++++++++++++++++++++++++++++++++++++++"; return; } - + //qDebug() << "x TestRangeOfxMoto: start+++++++++++++++++++++++++++++++++++++++++++"; ByteBack MotorState = m_xMotor->GetState(); //std::cout << "x马达速度:" << MotorState.Speed << std::endl; @@ -1111,7 +1141,7 @@ void HPPA::ontimerTestRangeOfxMotor() if (MotorState.Speed == 0 && MotorState.Location == 0)//处于位置为0的地方 { - std::cout << "开始测量x马达量程+++++++++++++++++++++++++++++++++++++++++++" << std::endl; + qDebug() << "x TestRangeOfxMotor: speed is 0,reach to original point+++++++++++++++++++++++++++++++++++++++++++"; m_xMotor->EnableMotro(); m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor); @@ -1120,21 +1150,15 @@ void HPPA::ontimerTestRangeOfxMotor() if (MotorState.Speed == 0 && MotorState.Location != 0)//处于位置最大的地方 { + qDebug() << "x TestRangeOfxMotor: speed is 0, reach to most far point, completed+++++++++++++++++++++++++++++++++++++++++++"; + m_xMotor->MoveToLocation(0); m_timerTestRangeOfxMotor->stop(); double maxDistance = ui.xmotor_location_slider->getDistanceFromPulse(MotorState.Location); //将x马达量程记录到文件,以便后面使用 → 不用每次都测试量程,这样很浪费时间 - - FileOperation * fileOperation = new FileOperation(); - string directory = fileOperation->getDirectoryOfExe(); - string xMotorRangeFile = directory + "\\xMotorRange"; - - FILE * motorRange = fopen(xMotorRangeFile.c_str(), "w+b"); - - fwrite(&maxDistance, sizeof(double), 1, motorRange); - fclose(motorRange); + configfile.setMaxRange(maxDistance, "x"); ui.xmotor_location_slider->setMaximum(maxDistance); ui.xmotor_max_location_label->setText(QString::number(ui.xmotor_location_slider->maximum())); @@ -1150,15 +1174,17 @@ void HPPA::ontimerTestRangeOfyMotor() { if (isMotorConnected(m_yMotor)) { - std::cout << "y马达有问题+++++++++++++++++++++++++++++++++++++++++++" << std::endl; + qDebug() << "y TestRangeOfxMotor: y motor is bad+++++++++++++++++++++++++++++++++++++++++++"; return; } ByteBack MotorState = m_yMotor->GetState(); + int a = 1; + //qDebug() << "y TestRangeOfyMoto: start"; if (MotorState.Speed == 0 && MotorState.Location == 0)//处于位置为0的地方 { - std::cout << "开始测量y马达量程+++++++++++++++++++++++++++++++++++++++++++" << std::endl; + qDebug() << "y TestRangeOfyMotor: speed is 0,reach to original point+++++++++++++++++++++++++++++++++++++++++++"; m_yMotor->EnableMotro(); m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor); @@ -1167,20 +1193,15 @@ void HPPA::ontimerTestRangeOfyMotor() if (MotorState.Speed == 0 && MotorState.Location != 0)//处于位置最大的地方 { + qDebug() << "y TestRangeOfyMotor: speed is 0, reach to most far point, completed+++++++++++++++++++++++++++++++++++++++++++"; + m_yMotor->MoveToLocation(0); m_timerTestRangeOfyMotor->stop(); double maxDistance = ui.ymotor_location_slider->getDistanceFromPulse(MotorState.Location); //将y马达量程记录到文件,以便后面使用 → 不用每次都测试量程,这样很浪费时间 - - FileOperation * fileOperation = new FileOperation(); - string directory = fileOperation->getDirectoryOfExe(); - string yMotorRangeFile = directory + "\\yMotorRange"; - - FILE * motorRange = fopen(yMotorRangeFile.c_str(), "w+b"); - fwrite(&maxDistance, sizeof(double), 1, motorRange); - fclose(motorRange); + configfile.setMaxRange(maxDistance, "y"); ui.ymotor_location_slider->setMaximum(maxDistance); ui.ymotor_max_location_label->setText(QString::number(ui.ymotor_location_slider->maximum())); @@ -1680,11 +1701,47 @@ void HPPA::newMotor() //马达 m_xMotor = new VinceControl(NETTCP, 6002);//相机轴 m_yMotor = new VinceControl(NETTCP, 6001);//原本:6001;韩工测试:6003 + if (imagerSelected == "mActionPica_NIR") + { + connect(m_xMotor, SIGNAL(newTCPConnection(VinceControl*)), this, SLOT(setMotorParamMicroscope(VinceControl*))); + connect(m_yMotor, SIGNAL(newTCPConnection(VinceControl*)), this, SLOT(setMotorParamMicroscope(VinceControl*))); + } + m_xConnectCount = 0; m_yConnectCount = 0; - connect(m_xMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString))); - connect(m_yMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString))); + + //connect(m_xMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString))); + //connect(m_yMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString))); +} + +void HPPA::setMotorParamMicroscope(VinceControl* motor) +{ + //显微镜nir的特殊配置 + QString commonstr; + QByteArray buf; + + commonstr = "cfg msr=2\n"; + motor->SendCommandtoMotor(commonstr, "non"); + motor->GetCommonRetrun(buf); + commonstr = "cfg msv=1\n"; + motor->SendCommandtoMotor(commonstr, "non"); + motor->GetCommonRetrun(buf); + + commonstr = "cfg psr=1\n"; + motor->SendCommandtoMotor(commonstr, "non"); + motor->GetCommonRetrun(buf); + commonstr = "cfg psv=1\n"; + motor->SendCommandtoMotor(commonstr, "non"); + motor->GetCommonRetrun(buf); + + commonstr = "cfg zsd=-3000\n";//设置归零速度和方向 + motor->SendCommandtoMotor(commonstr, "non"); + motor->GetCommonRetrun(buf); + + commonstr = "cfg snr=1\n";//设置归零传感器 + motor->SendCommandtoMotor(commonstr, "non"); + motor->GetCommonRetrun(buf); } void HPPA::deleteMotor() @@ -1775,7 +1832,33 @@ void HPPA::onconnect() { //采集影像线程:放入新线程中采集以免在采集过程中界面卡死:https://www.cnblogs.com/xia-weiwen/p/10306089.html m_RecordThread = new QThread(); - m_Imager = new ResononImager(); + + //根据选择的相机类型创建对象mImagerGroup + if (imagerSelected == "mActionPica_L") + { + m_Imager = new ResononPicaLImager(); + } + else if (imagerSelected == "mActionPica_NIR") + { + m_Imager = new ResononNirImager(); + } + else if (imagerSelected == "mActionPika_XC2") + { + + } + else if (imagerSelected == "mActionCorning_410") + { + + } + else + { + QMessageBox msgBox; + msgBox.setText(QString::fromLocal8Bit("请选择相机!")); + msgBox.exec(); + + return; + } + m_Imager->moveToThread(m_RecordThread); m_RecordThread->start(); @@ -1787,6 +1870,8 @@ void HPPA::onconnect() connect(m_Imager, SIGNAL(SpectralSignal(int)), this, SLOT(PlotSpectral(int))); //connect(m_Imager, SIGNAL(testImagerStatus()), this, SLOT(testImagerStatus())); + newMotor();//会根据不同的相机类型,为线性平台设置不同的参数,所以在连接相机后创建马达; + //文件拷贝 m_CopyFileThread = new QThread(); @@ -1843,18 +1928,20 @@ void HPPA::onconnect() ui.gain_lineEdit->setValidator(new QRegExpValidator(rx));*/ //获取相机参数并显示到界面中 - ui.framerate_lineEdit->setText(QString::number(m_Imager->get_framerate(), 10, 2)); - ui.FramerateSlider->setValue(m_Imager->get_framerate(), true); + ui.framerate_lineEdit->setText(QString::number(m_Imager->getFramerate(), 10, 2)); + ui.FramerateSlider->setValue(m_Imager->getFramerate(), true); CalculateIntegratioinTimeRange(); - ui.integratioin_time_lineEdit->setText(QString::number(m_Imager->get_integration_time(), 10, 2)); - ui.IntegratioinTimeSlider->setValue(m_Imager->get_integration_time()); + ui.integratioin_time_lineEdit->setText(QString::number(m_Imager->getIntegrationTime(), 10, 2)); + ui.IntegratioinTimeSlider->setValue(m_Imager->getIntegrationTime()); - ui.gain_lineEdit->setText(QString::number(m_Imager->get_gain(), 10, 2)); - ui.GainSlider->setValue(m_Imager->get_gain()); + ui.gain_lineEdit->setText(QString::number(m_Imager->getGain(), 10, 2)); + ui.GainSlider->setValue(m_Imager->getGain()); } - catch (...) + catch (std::exception const& e) { + std::cerr << "Error: " << e.what() << std::endl; + delete m_Imager; m_Imager = nullptr; diff --git a/HPPA/HPPA.h b/HPPA/HPPA.h index 7f4b5ac..3e5bbd3 100644 --- a/HPPA/HPPA.h +++ b/HPPA/HPPA.h @@ -33,6 +33,8 @@ #include "hppaConfigFile.h" #include "path_tc.h" +#include "ResononNirImager.h" + #define PI 3.1415926 QT_CHARTS_USE_NAMESPACE//QChartView 使用 需要加宏, 否则无法使用 @@ -44,9 +46,9 @@ private: public: - ResononImager *m_Imager; + ImagerOperationBase*m_Imager; - WorkerThread(ResononImager * Imager) + WorkerThread(ImagerOperationBase* Imager) { m_Imager = Imager; } @@ -163,8 +165,10 @@ private: QLabel * xmotor_state_label1; QLabel * ymotor_state_label1; + Configfile configfile; + ForLoopControl * m_ForLoopControl; - ResononImager * m_Imager;// + ImagerOperationBase* m_Imager;// int m_RecordState;//用来控制相机采集流程,取2的余数,1 → 正在采集,0 → 停止采集 @@ -205,6 +209,7 @@ private: //马达 void deleteMotor(); void newMotor(); + bool isMotorConnected(VinceControl *motor);//判断马达是否断开:如果断开返回true;否则返回false void SetXMotorWidgetEnable(bool enable); void SetYMotorWidgetEnable(bool enable); @@ -224,6 +229,11 @@ private: void getRequest(QString str); + QActionGroup* mImagerGroup = nullptr; + QString imagerSelected; + void createActionGroups(); + void selectingImager(QAction* selectedAction); + public Q_SLOTS: void onPlotHyperspectralImageRgbImage(); void PlotSpectral(int state); @@ -258,6 +268,7 @@ public Q_SLOTS: //马达 void timerEvent(QTimerEvent *event); + void setMotorParamMicroscope(VinceControl* motor); void onxMotorLeft(); diff --git a/HPPA/HPPA.ui b/HPPA/HPPA.ui index df5e09d..f3adf8d 100644 --- a/HPPA/HPPA.ui +++ b/HPPA/HPPA.ui @@ -6,8 +6,8 @@ 0 0 - 2213 - 1262 + 1643 + 831 @@ -18,7 +18,7 @@ :/HPPA/HPPA.ico:/HPPA/HPPA.ico - background-color: rgb(240, 240, 240); + @@ -51,7 +51,7 @@ - 500 + 200 0 @@ -92,7 +92,20 @@ false - border-size:1px; + QGroupBox { + /* border: 2px solid #3498db; 杈规棰滆壊 */ + border-radius: 5px; /* 鍦嗚 */ + padding: 10px; /* 鍐呰竟璺 */ + background-color: rgb(255, 255, 255); +} + +QGroupBox:title { + subcontrol-position: top left; /* 鏍囬浣嶇疆 */ + padding: 0 10px; /* 鏍囬鍐呰竟璺 */ + font-weight: bold; /* 鏍囬瀛椾綋鍔犵矖 */ + color: #3498db; /* 鏍囬鏂囧瓧棰滆壊 */ +} + @@ -101,14 +114,14 @@ - 鎵撳紑鎽勫儚澶 + 鎵撳紑 - 鍏抽棴鎽勫儚澶 + 鍏抽棴 @@ -284,12 +297,33 @@ 16777215 + + QTabWidget::pane { + border: 1px solid #ccc; /* 閫夐」鍗¢潰鏉胯竟妗嗛鑹 */ + border-radius: 5px; /* 閫夐」鍗¢潰鏉垮渾瑙 */ + +} + +QTabBar::tab { + background: #f0f0f0; /* 閫夐」鍗¤儗鏅鑹 */ + border: 1px solid #ccc; /* 閫夐」鍗¤竟妗嗛鑹 */ + padding: 10px; /* 鍐呰竟璺 */ + border-radius: 5px; /* 閫夐」鍗″渾瑙 */ + font-size:20px; +} + +QTabBar::tab:selected { + background: #3498db; /* 婵娲荤姸鎬侀夐」鍗¤儗鏅鑹 */ + color: white; /* 婵娲荤姸鎬侀夐」鍗℃枃瀛楅鑹 */ +} + + - 4 + 0 - camera + 鍏夎氨浠 @@ -456,6 +490,12 @@ + + + 0 + 0 + + background-color: rgb(255, 255, 255); @@ -483,6 +523,12 @@ + + + 0 + 0 + + Qt::Horizontal @@ -507,7 +553,7 @@ - stage + 绾挎у钩鍙 @@ -642,7 +688,7 @@ - 椹揪閲忕▼妫娴 + 閲忕▼妫娴 @@ -1055,9 +1101,9 @@ - + - + 0 0 @@ -1160,7 +1206,7 @@ - + 0 @@ -1799,28 +1845,56 @@ 0 0 - 2213 - 30 + 1643 + 33 + + QMenuBar{ +background:rgb(255,255,255); +color:rgb(0,0,0); +font-size:16px; +padding:2px; +border:1px solid rgb(165,171,184); +} +QMenuBar::item{ +background:rgb(255,255,255); +width:52px; +height:24px; +} +QMenuBar::item:selected{ +background:rgb(185,196,221); +} +QMenu{ +background:rgb(255,255,255); +color:rgb(0,0,0); +border:1px solid rgb(165,171,184); +} +QMenu::item:selected{ +background:rgb(69,123,255); +color:white; +} + + - file + 鏂囦欢 - spectrometer + 鍏夎氨浠 閫夋嫨鐩告満绫诲瀷 - - + + + - + @@ -1836,7 +1910,7 @@ - help + 甯姪 @@ -1851,6 +1925,23 @@ 0 + + QToolBar{ + background:rgb(255,255,255); + color:rgb(0,0,0); +} +QToolBar QToolButton { + background: rgb(255,255,255); /* 鎸夐挳鑳屾櫙棰滆壊 */ + font-size:15px; + border-radius: 3px; /* 鎸夐挳鍦嗚 */ + padding: 4px; /* 鎸夐挳鍐呰竟璺 */ +} +QToolBar QToolButton:hover { + background: rgb(185,196,221); /* 鎸夐挳鎮仠鑳屾櫙棰滆壊 */ + color: white; /* 鎸夐挳鎮仠鏂囧瓧棰滆壊 */ +} + + TopToolBarArea @@ -1865,10 +1956,21 @@ - + + + QStatusBar { + + background-color: rgb(255, 255, 255); + color: white; /* 鏂囧瓧棰滆壊 */ + border-top: 1px solid #ccc; /* 椤堕儴杈规 */ + padding: 5px; /* 鍐呰竟璺 */ +} + + + - exit + 閫鍑 @@ -1919,24 +2021,41 @@ 鎵撳紑鏂囦欢澶 - + + + true + Pika L - + + + true + Corning 410 - + + + true + Pika XC2 - about + 鍏充簬 + + + + + true + + + Pika NIR @@ -1957,11 +2076,6 @@ QGraphicsView
imagerpositionsimulation.h
- - QYMotorDoubleSlider - QSlider -
QYMotorDoubleSlider.h
-
diff --git a/HPPA/HPPA.vcxproj b/HPPA/HPPA.vcxproj index c21bf05..fef7ce4 100644 --- a/HPPA/HPPA.vcxproj +++ b/HPPA/HPPA.vcxproj @@ -55,16 +55,17 @@ - D:\cpp_library\gdal2.2.3_vs2017\include;C:\Program Files\ResononAPI\include;D:\cpp_library\opencv3.4.11\opencv\build\include;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv2;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PCOMM\Include;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PortControl;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL;D:\cpp_project_vs2022\HPPA\HPPA;D:\cpp_library\libconfig-1.7.3\lib;D:\cpp_project_vs2022\HPPA - 鍓湰\vincecontrol;$(IncludePath) - D:\cpp_library\opencv3.4.11\opencv\build\x64\vc15\lib;D:\cpp_library\gdal2.2.3_vs2017\lib;C:\Program Files\ResononAPI\lib64;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\x64\Debug;D:\cpp_library\libconfig-1.7.3\build\x64;D:\cpp_project_vs2022\HPPA - 鍓湰\vincecontrol\x64\Debug;$(LibraryPath) + D:\cpp_library\gdal2.2.3_vs2017\include;C:\Program Files\ResononAPI\include;D:\cpp_library\opencv3.4.11\opencv\build\include;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv2;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PCOMM\Include;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PortControl;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL;D:\cpp_project_vs2022\HPPA\HPPA;D:\cpp_library\libconfig-1.7.3\lib;D:\cpp_project_vs2022\HPPA\vincecontrol;D:\cpp_library\vincecontrol_vs2017;$(IncludePath) + D:\cpp_library\opencv3.4.11\opencv\build\x64\vc15\lib;D:\cpp_library\gdal2.2.3_vs2017\lib;C:\Program Files\ResononAPI\lib64;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\x64\Debug;D:\cpp_library\libconfig-1.7.3\build\x64;D:\cpp_project_vs2022\HPPA\x64\Debug;$(LibraryPath) - D:\cpp_library\vincecontrol_vs2017;D:\cpp_library\gdal2.2.3_vs2017\include;C:\Program Files\ResononAPI\include;D:\cpp_library\opencv3.4.11\opencv\build\include;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv2;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PCOMM\Include;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PortControl;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL;D:\cpp_project_vs2022\HPPA\HPPA;D:\cpp_library\libconfig-1.7.3\lib;$(IncludePath) + D:\cpp_library\gdal2.2.3_vs2017\include;C:\Program Files\ResononAPI\include;D:\cpp_library\opencv3.4.11\opencv\build\include;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv;D:\cpp_library\opencv3.4.11\opencv\build\include\opencv2;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PCOMM\Include;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL\SDKs\PortControl;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\AutoFocus_InspireLinearMotor_DLL;D:\cpp_project_vs2022\HPPA\HPPA;D:\cpp_library\libconfig-1.7.3\lib;D:\cpp_project_vs2022\HPPA\vincecontrol;$(IncludePath) D:\cpp_library\opencv3.4.11\opencv\build\x64\vc15\lib;D:\cpp_library\vincecontrol_vs2017_release;D:\cpp_library\gdal2.2.3_vs2017\lib;C:\Program Files\ResononAPI\lib64;D:\cpp_project_vs2022\AutoFocus_InspireLinearMotor_DLL\x64\Release;D:\cpp_library\libconfig-1.7.3\build\x64;$(LibraryPath) - opencv_world3411.lib;opencv_world3411d.lib;gdal_i.lib;resonon-basler.lib;AutoFocus_InspireLinearMotor_DLL.lib;libconfig++d.lib;vincecontrol.lib;%(AdditionalDependencies) + opencv_world3411.lib;opencv_world3411d.lib;gdal_i.lib;resonon-basler.lib;AutoFocus_InspireLinearMotor_DLL.lib;libconfig++d.lib;vincecontrol.lib;resonon-allied.lib;%(AdditionalDependencies) + D:\cpp_project_vs2022\HPPA\x64\Debug;%(AdditionalLibraryDirectories) %(PreprocessorDefinitions) @@ -72,7 +73,8 @@ - opencv_world3411.lib;vincecontrol.lib;gdal_i.lib;resonon-basler.lib;AutoFocus_InspireLinearMotor_DLL.lib;libconfig++.lib;%(AdditionalDependencies) + opencv_world3411.lib;vincecontrol.lib;gdal_i.lib;resonon-basler.lib;resonon-allied.lib;AutoFocus_InspireLinearMotor_DLL.lib;libconfig++.lib;%(AdditionalDependencies) + D:\cpp_project_vs2022\HPPA\x64\Release;%(AdditionalLibraryDirectories) @@ -104,16 +106,18 @@ + - + Create Create + @@ -140,16 +144,18 @@ + + + - diff --git a/HPPA/HPPA.vcxproj.filters b/HPPA/HPPA.vcxproj.filters index 9e8cbea..c895583 100644 --- a/HPPA/HPPA.vcxproj.filters +++ b/HPPA/HPPA.vcxproj.filters @@ -70,9 +70,6 @@ Source Files - - Source Files - Source Files @@ -91,6 +88,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -117,9 +123,6 @@ Header Files - - Header Files - Header Files @@ -129,6 +132,9 @@ Header Files + + Header Files + @@ -149,6 +155,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/HPPA/ImagerOperationBase.cpp b/HPPA/ImagerOperationBase.cpp new file mode 100644 index 0000000..23c02ac --- /dev/null +++ b/HPPA/ImagerOperationBase.cpp @@ -0,0 +1,399 @@ +#include "ImagerOperationBase.h" + +ImagerOperationBase::ImagerOperationBase() +{ + m_iFrameCounter = 1; + m_bRecordControlState = true; + + m_FileName2Save = "tmp_image"; + m_FileSavedCounter = 1; + + 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) >= 4095) + { + setIntegrationTime(getIntegrationTime() * 0.8); + std::cout << "自动曝光-----------" << std::endl; + } + else + { + break; + } + } + + imagerStopCollect(); + + //std::cout << "自动曝光:" << getIntegrationTime() << std::endl; + + return getIntegrationTime(); +} + +void ImagerOperationBase::focus() +{ + m_iFocusFrameCounter = 1; + //std::cout << "调焦-----------" << std::endl; + + double tmpFrmerate = getFramerate(); + double tmpIntegrationTime = getIntegrationTime(); + + + setFramerate(5); + auto_exposure(); + std::cout << "调焦获得的曝光时间为:" << getIntegrationTime() << std::endl; + + 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(); + + setFramerate(tmpFrmerate); + setIntegrationTime(tmpIntegrationTime); +} + +void ImagerOperationBase::record_dark() +{ + std::cout << "采集暗电流!!!!!!!!!" << std::endl; + imagerStartCollect(); + getFrame(dark); + imagerStopCollect(); + + m_HasDark = true; +} + +void ImagerOperationBase::record_white() +{ + std::cout << "采集暗白板!!!!!!!!!" << std::endl; + imagerStartCollect(); + getFrame(white); + 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; +} + +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); + } + + FileOperation* fileOperation = new FileOperation(); + string directory = fileOperation->getDirectoryFromString(); + string imgPath = directory + "\\" + m_FileName2Save + "_" + std::to_string(m_FileSavedCounter); + + FILE* m_fImage = fopen(imgPath.c_str(), "w+b"); + + size_t x; + double pixelValueTmp; + + imagerStartCollect(); + while (m_bRecordControlState) + { + m_iFrameCounter++; + + getFrame(buffer); + + //减去暗电流,应为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); + + //将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; + } + + } + 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); +} + +void ImagerOperationBase::setFrameNumber(int FrameNumber) +{ + m_iFrameNumber = FrameNumber; + m_RgbImage->SetRgbImageWidthAndHeight(getBandCount(), getSampleCount(), FrameNumber); +} + +void ImagerOperationBase::setFileName2Save(string FileName) +{ + m_FileName2Save = FileName; + m_FileSavedCounter = 1; +} + +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; +} + +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; +} + +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; + + + FileOperation* fileOperation = new FileOperation(); + string directory = fileOperation->getDirectoryFromString(); + + string hdrPath = directory + "\\" + m_FileName2Save + "_" + std::to_string(m_FileSavedCounter) + ".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 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; +} diff --git a/HPPA/ImagerOperationBase.h b/HPPA/ImagerOperationBase.h new file mode 100644 index 0000000..1674099 --- /dev/null +++ b/HPPA/ImagerOperationBase.h @@ -0,0 +1,102 @@ +#pragma once +#include +#include + +#include "image2display.h" +#include "fileOperation.h" +#include +#include +#include "ImagerOperationBase.h" + +class ImagerOperationBase :public QObject +{ + Q_OBJECT + +public: + ImagerOperationBase(); + ~ImagerOperationBase(); + + virtual double getWavelengthAtBand(int band) = 0; + virtual int getBandCount() = 0; + virtual int getSampleCount() = 0; + virtual double getFramerate() = 0; + virtual double getIntegrationTime() = 0; + virtual double getGain() = 0; + virtual void setFramerate(const double frames_per_second) = 0; + virtual void setIntegrationTime(const double milliseconds) = 0; + virtual void setGain(const double gain) = 0; + virtual int getStartBand() = 0; + virtual int getEndBand() = 0; + virtual void connectImager(const char* camera_sn = NULL) = 0; + virtual void disconnectImager() = 0; + virtual void imagerStartCollect() = 0; + virtual void imagerStopCollect() = 0; + virtual unsigned short* getFrame(unsigned short* buffer) = 0; + virtual void setSpectraBin(int new_spectral_bin) = 0; + + + CImage* getRgbImage() const; + cv::Mat* getMatRgbImage() const; + cv::Mat* getMatFocusGrayImage() const; + QImage getQImageFocusGrayImage() const; + + bool getRecordControlState() const; + void setRecordControlState(bool RecordControlState); + + int getFrameCounter() const; + int getFocusFrameCounter() const; + + unsigned short* buffer;//存储采集到的影像的中间变量,下一步写入到硬盘中 + void set_buffer(); + void setFileName2Save(string FileName); + + void setFrameNumber(int FrameNumber); + void setFocusControlState(bool FocusControlState); + int GetFrameSize(int& iWidth, int& iHeight); + + +protected: + CImage* m_RgbImage;//显示的rgb图像 + bool m_bRecordControlState;//采集状态;可用于执行停止采集操作 + int m_iFrameCounter;//记录采集的帧数 + int m_iFocusFrameCounter;//记录调焦时采集的帧数 + int m_FrameSize;//表示一帧代表有多少个数值:m_FrameSize = m_imager.get_band_count()*m_imager.get_sample_count(); + int m_iFrameNumber;//需要采集的总帧数 + + //以下两个参数用于给保存的影像文件命名 + string m_FileName2Save;//保存的影像文件名 + int m_FileSavedCounter;//保存了几个影像文件 + + bool m_HasDark;//当采集了暗电流之后,设置为true + bool m_HasWhite;//当采集了白板之后,设置为true + + unsigned short* dark;//存储暗电流 + unsigned short* white;//存储白板 + + bool m_bFocusControlState;//控制调焦结束 + + + + virtual void WriteHdr(); + unsigned short GetMaxValue(unsigned short* dark, int number); + + + +private: + +public slots: + virtual void connect_imager(int frameNumber);//连接相机、开辟缓存 + virtual double auto_exposure(); + virtual void focus(); + virtual void start_record(); + virtual void record_dark(); + virtual void record_white(); +signals: + void PlotSignal();//绘制影像信号 + void RecordFinishedSignal_WhenFrameNumberMeet();//采集完成信号:需要采集的总帧数(m_iFrameNumber)采集完成 + void RecordFinishedSignal_WhenFrameNumberNotMeet();//采集完成信号:需要采集的总帧数(m_iFrameNumber)没有采集完成,中途停止采集 + void SpectralSignal(int);//发射1代表正在调焦,绘制光谱,发射0表示调焦完成; + + + void testImagerStatus();//表示可以测试相机连接状态:是否连接,并反映到界面上 +}; diff --git a/HPPA/QMotorDoubleSlider.cpp b/HPPA/QMotorDoubleSlider.cpp index c86e399..464a66d 100644 --- a/HPPA/QMotorDoubleSlider.cpp +++ b/HPPA/QMotorDoubleSlider.cpp @@ -9,24 +9,15 @@ QMotorDoubleSlider::QMotorDoubleSlider(QWidget* pParent /*= NULL*/) :QSlider(pPa setOrientation(Qt::Horizontal); setFocusPolicy(Qt::NoFocus); - //读取配置文件 - string HPPACfgFile = getPathofEXE() + "\\HPPA.cfg"; - Configfile configfile; - configfile.setConfigfilePath(HPPACfgFile); - if (!configfile.isConfigfileExist()) - configfile.createConfigFile(); - configfile.parseConfigfile(); - - float Lead_x;//导程 - float StepAnglemar_x;//步距角 - float ScaleFactor_x;//因机械装置的原因引入的缩放因子 - int SubdivisionMultiples_x;//细分数 - configfile.getXMotorParm(StepAnglemar_x, Lead_x, SubdivisionMultiples_x, ScaleFactor_x); + m_Multiplier = 0; +} +void QMotorDoubleSlider::setMultiplier(float lead, float stepAnglemar, float scaleFactor, int subdivisionMultiples) +{ //根据公式将脉冲换算为距离:1脉冲距离(m_Multiplier)=导程/(360/步距角*细分倍数);网址:https://wenku.baidu.com/view/4b2ea88bd0d233d4b14e69b8.html //m_Multiplier(0.00054496986),//上海农科院,修改前:0.00052734375/5=0.00010546875;修改后准确值为0.000544969862759644,近似为0.00054496986/5=0.000108993972,因为有个机械装置1脉冲距离需要除以5; //m_Multiplier(0.00054496986)//兴安盟农研所 - m_Multiplier = Lead_x / (360 / StepAnglemar_x * SubdivisionMultiples_x) * ScaleFactor_x; + m_Multiplier = lead / (360 / stepAnglemar * subdivisionMultiples) * scaleFactor; } //向外发射 diff --git a/HPPA/QMotorDoubleSlider.h b/HPPA/QMotorDoubleSlider.h index de1c43d..371afb6 100644 --- a/HPPA/QMotorDoubleSlider.h +++ b/HPPA/QMotorDoubleSlider.h @@ -12,8 +12,9 @@ class QMotorDoubleSlider : public QSlider public: QMotorDoubleSlider(QWidget* pParent = NULL); + void setMultiplier(float lead, float stepAnglemar, float scaleFactor, int subdivisionMultiples); - double m_Multiplier; + double m_Multiplier;//根据公式将脉冲换算为距离:1脉冲距离(m_Multiplier)=导程/(360/步距角*细分倍数);网址:https://wenku.baidu.com/view/4b2ea88bd0d233d4b14e69b8.html void setRange(double Min, double Max); void setMinimum(double Min); @@ -25,17 +26,15 @@ public: long getPositionPulse(double position);//根据传入的距离返回脉冲值 double getDistanceFromPulse(int pulse); - public slots: +public slots: void notifyValueChanged(int value);//信号valueChanged(int)的wrap void setValue(double Value, bool BlockSignals = true);//QSlider::setValue函数的wrap - private slots: - -signals : +signals: void valueChanged(double Value); void rangeChanged(double Min, double Max); private: }; -#endif \ No newline at end of file +#endif diff --git a/HPPA/QYMotorDoubleSlider.cpp b/HPPA/QYMotorDoubleSlider.cpp deleted file mode 100644 index 8e4f16b..0000000 --- a/HPPA/QYMotorDoubleSlider.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "stdafx.h" -#include "QYMotorDoubleSlider.h" -QYMotorDoubleSlider::QYMotorDoubleSlider(QWidget* pParent /*= NULL*/) :QSlider(pParent) -{ - connect(this, SIGNAL(valueChanged(int)), this, SLOT(notifyValueChanged(int))); - - setSingleStep(1); - - setOrientation(Qt::Horizontal); - setFocusPolicy(Qt::NoFocus); - - //配置文件 - string HPPACfgFile = getPathofEXE() + "\\HPPA.cfg"; - Configfile configfile; - configfile.setConfigfilePath(HPPACfgFile); - if (!configfile.isConfigfileExist()) - configfile.createConfigFile(); - configfile.parseConfigfile(); - - float StepAnglemar_y; - float Lead_y; - float ScaleFactor_y;//因机械装置的原因引入的缩放因子 - int SubdivisionMultiples_y; - configfile.getYMotorParm(StepAnglemar_y, Lead_y, SubdivisionMultiples_y, ScaleFactor_y); - - //m_Multiplier(0.000108993972),//上海农科院,修改前:0.00052734375/5=0.00010546875;修改后准确值为0.000544969862759644,近似为0.00054496986/5=0.000108993972,因为有个机械装置1脉冲距离需要除以5; - //m_Multiplier(0.000108993972)//兴安盟农研所 - m_Multiplier = Lead_y / (360 / StepAnglemar_y * SubdivisionMultiples_y) * ScaleFactor_y; -} - -//向外发射 -void QYMotorDoubleSlider::notifyValueChanged(int Value) -{ - emit valueChanged((double)Value * m_Multiplier);////////// -} - -//接收外边 -void QYMotorDoubleSlider::setValue(double Value, bool BlockSignals) -{ - QSlider::blockSignals(BlockSignals); - - QSlider::setValue(Value / m_Multiplier);//////////// - - if (!BlockSignals) - emit valueChanged(Value); - - QSlider::blockSignals(false); -} - -void QYMotorDoubleSlider::setRange(double Min, double Max) -{ - QSlider::setRange(Min / m_Multiplier, Max / m_Multiplier);////// - - emit rangeChanged(Min, Max); -} - -void QYMotorDoubleSlider::setMinimum(double Min) -{ - QSlider::setMinimum(Min / m_Multiplier);////// - - emit rangeChanged(minimum(), maximum()); -} - -double QYMotorDoubleSlider::minimum() const -{ - return QSlider::minimum() * m_Multiplier;///// -} - -void QYMotorDoubleSlider::setMaximum(double Max) -{ - QSlider::setMaximum(Max / m_Multiplier);////// - - emit rangeChanged(minimum(), maximum()); -} - -double QYMotorDoubleSlider::maximum() const -{ - return QSlider::maximum() * m_Multiplier;/////// -} - -double QYMotorDoubleSlider::value() const -{ - int Value = QSlider::value(); - return (double)Value * m_Multiplier;////// -} - -double QYMotorDoubleSlider::OriginalValue() const -{ - int Value = QSlider::value(); - return (double)Value; -} - -long QYMotorDoubleSlider::getPositionPulse(double position) -{ - return position / m_Multiplier; -} - -double QYMotorDoubleSlider::getDistanceFromPulse(int pulse) -{ - return pulse * m_Multiplier; -} diff --git a/HPPA/QYMotorDoubleSlider.h b/HPPA/QYMotorDoubleSlider.h deleted file mode 100644 index b0854fd..0000000 --- a/HPPA/QYMotorDoubleSlider.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef Q_YMOTOR_DOUBLE_SLIDER_H -#define Q_YMOTOR_DOUBLE_SLIDER_H -#include -#include - -#include "hppaConfigFile.h" -#include "path_tc.h" - -class QYMotorDoubleSlider : public QSlider//QYMotorDoubleSlider -{ - Q_OBJECT - -public: - QYMotorDoubleSlider(QWidget* pParent = NULL); - - double m_Multiplier;//根据公式将脉冲换算为距离:1脉冲距离(m_Multiplier)=导程/(360/步距角*细分倍数);网址:https://wenku.baidu.com/view/4b2ea88bd0d233d4b14e69b8.html - - void setRange(double Min, double Max); - void setMinimum(double Min); - double minimum() const; - void setMaximum(double Max); - double maximum() const; - double value() const; - double OriginalValue() const;//返回脉冲值:马达需要实际的脉冲值,而不是距离 - long getPositionPulse(double position);//根据传入的距离返回脉冲值 - double getDistanceFromPulse(int pulse); - - public slots: - void notifyValueChanged(int value);//信号valueChanged(int)的wrap - void setValue(double Value, bool BlockSignals = true);//QSlider::setValue函数的wrap - - private slots: - -signals : - void valueChanged(double Value); - void rangeChanged(double Min, double Max); - -private: - -}; -#endif \ No newline at end of file diff --git a/HPPA/ResononNirImager.cpp b/HPPA/ResononNirImager.cpp new file mode 100644 index 0000000..214dc36 --- /dev/null +++ b/HPPA/ResononNirImager.cpp @@ -0,0 +1,338 @@ +#include "stdafx.h" +#include +#include +#include +#include +#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(); + Sleep(20); + setFramerate(tmpFrmerate);//为啥就在这里设置帧率要报错?而在界面上拖动设置帧率就不报错? + + + reConnectImage(); + setIntegrationTime(tmpIntegrationTime); +} + +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); + } + + FileOperation* fileOperation = new FileOperation(); + string directory = fileOperation->getDirectoryFromString(); + string imgPath = directory + "\\" + m_FileName2Save + "_" + std::to_string(m_FileSavedCounter); + + FILE* m_fImage = fopen(imgPath.c_str(), "w+b"); + + size_t x; + double pixelValueTmp; + + reConnectImage();//nir第二次采集时需要重新连接相机,否则函数imagerStartCollect()会报错。。。。。。 + imagerStartCollect(); + while (m_bRecordControlState) + { + m_iFrameCounter++; + + getFrame(buffer); + + //减去暗电流,应为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); + + //将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; + } + + } + 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); +} + +void ResononNirImager::WriteHdr() +{ + //write an ENVI compatible header file + using namespace std; + + + FileOperation* fileOperation = new FileOperation(); + string directory = fileOperation->getDirectoryFromString(); + + string hdrPath = directory + "\\" + m_FileName2Save + "_" + std::to_string(m_FileSavedCounter) + ".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(); +} diff --git a/HPPA/ResononNirImager.h b/HPPA/ResononNirImager.h new file mode 100644 index 0000000..a755ba8 --- /dev/null +++ b/HPPA/ResononNirImager.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +#include "ImagerOperationBase.h" +#include "resonon_imager_allied.h" +#include "image2display.h" +#include "fileOperation.h" + +class ResononNirImager :public ImagerOperationBase +{ +public: + ResononNirImager(); + ~ResononNirImager(); + + Resonon::PikaAllied m_ResononNirImager;// + + double getWavelengthAtBand(int band); + int getBandCount(); + int getSampleCount(); + double getFramerate(); + double getIntegrationTime(); + double getGain(); + void setFramerate(const double frames_per_second); + void setIntegrationTime(const double milliseconds); + void setGain(const double gain); + int getStartBand(); + int getEndBand(); + void connectImager(const char* camera_sn = NULL); + void disconnectImager(); + void imagerStartCollect(); + void imagerStopCollect(); + unsigned short* getFrame(unsigned short* buffer); + void setSpectraBin(int new_spectral_bin); + + void WriteHdr(); + +protected: +private: + void reConnectImage(); + +public slots: + double auto_exposure(); + void focus(); + void start_record(); + +signals: + +}; diff --git a/HPPA/about.ui b/HPPA/about.ui index 32279c4..9dbae74 100644 --- a/HPPA/about.ui +++ b/HPPA/about.ui @@ -70,7 +70,7 @@ - 鐗堟湰锛1.7 + 鐗堟湰锛1.8
diff --git a/HPPA/focusWindow.cpp b/HPPA/focusWindow.cpp index 3386278..ba26738 100644 --- a/HPPA/focusWindow.cpp +++ b/HPPA/focusWindow.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "focusWindow.h" -focusWindow::focusWindow(QWidget *parent, ResononImager * imager) +focusWindow::focusWindow(QWidget *parent, ImagerOperationBase* imager) { ui.setupUi(this); @@ -77,12 +77,12 @@ bool test(void *pCaller, int *x, int *y, void **pvdata) { focusWindow *p = (focusWindow *)pCaller; - p->m_Imager->GetImageSize(*x, *y); + p->m_Imager->GetFrameSize(*x, *y); USHORT *pusData = new USHORT[(*x)*(*y)]; - p->m_Imager->m_ResononImager.start(); - p->m_Imager->m_ResononImager.get_frame(pusData); - p->m_Imager->m_ResononImager.stop(); + p->m_Imager->imagerStartCollect(); + p->m_Imager->getFrame(pusData); + p->m_Imager->imagerStopCollect(); BYTE *pbData = (BYTE*)pusData; diff --git a/HPPA/focusWindow.h b/HPPA/focusWindow.h index 0110066..2466a71 100644 --- a/HPPA/focusWindow.h +++ b/HPPA/focusWindow.h @@ -25,6 +25,7 @@ #include "hppaConfigFile.h" #include "path_tc.h" +#include "ImagerOperationBase.h" class focusWindow:public QDialog { @@ -32,10 +33,10 @@ class focusWindow:public QDialog public: focusWindow(QWidget *parent = Q_NULLPTR); - focusWindow(QWidget *parent, ResononImager * imager); + focusWindow(QWidget *parent, ImagerOperationBase* imager); ~focusWindow(); - ResononImager * m_Imager; + ImagerOperationBase* m_Imager; private: diff --git a/HPPA/hppaConfigFile.cpp b/HPPA/hppaConfigFile.cpp index d59c644..3355e47 100644 --- a/HPPA/hppaConfigFile.cpp +++ b/HPPA/hppaConfigFile.cpp @@ -155,7 +155,7 @@ bool Configfile::getAutoFocusRange(int& max, int& min) return true; } -bool Configfile::getXMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor) +bool Configfile::getXMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor, float& MaxRange) { const Setting& root = cfg.getRoot(); @@ -170,6 +170,7 @@ bool Configfile::getXMotorParm(float& StepAnglemar, float& Lead, int& Subdivisio if (!(x.lookupValue("StepAnglemar", StepAnglemar) && x.lookupValue("Lead", Lead) && x.lookupValue("SubdivisionMultiples", SubdivisionMultiples) && x.lookupValue("ScaleFactor", ScaleFactor) + && x.lookupValue("MaxRange", MaxRange) )) { return false; @@ -184,7 +185,7 @@ bool Configfile::getXMotorParm(float& StepAnglemar, float& Lead, int& Subdivisio return true; } -bool Configfile::getYMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor) +bool Configfile::getYMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor, float& MaxRange) { const Setting& root = cfg.getRoot(); @@ -199,6 +200,7 @@ bool Configfile::getYMotorParm(float& StepAnglemar, float& Lead, int& Subdivisio if (!(y.lookupValue("StepAnglemar", StepAnglemar) && y.lookupValue("Lead", Lead) && y.lookupValue("SubdivisionMultiples", SubdivisionMultiples) && y.lookupValue("ScaleFactor", ScaleFactor) + && y.lookupValue("MaxRange", MaxRange) )) { return false; @@ -213,6 +215,43 @@ bool Configfile::getYMotorParm(float& StepAnglemar, float& Lead, int& Subdivisio return true; } +bool Configfile::setMaxRange(float maxRange, QString x_y) +{ + const Setting& root = cfg.getRoot(); + try + { + Setting& _maxRange = root["motionPlatform"][x_y.toStdString()]["MaxRange"]; + _maxRange = maxRange; + + writeConfig2File(); + + return true; + } + catch (const SettingNotFoundException& nfex) + { + cerr << "No 'MaxRange' setting in configuration file." << endl; + return false; + } +} + +bool Configfile::writeConfig2File() +{ + try + { + QList fileInfo = getFileInfo(QString::fromStdString(m_configfilePath)); + bool ret = createDir(fileInfo[0]); + + cfg.writeFile(m_configfilePath.c_str()); + // cerr << "New configuration successfully written to: " << m_configfilePath.c_str() << endl; + } + catch (const FileIOException& fioex) + { + cerr << "I/O error while writing configuration file: " << m_configfilePath.c_str() << endl; + return false; + } + return true; +} + bool Configfile::getSN(string &SN) { try @@ -266,10 +305,12 @@ bool Configfile::createConfigFile() Setting& x_Lead = x.add("Lead", Setting::TypeFloat) = 13.5;//导程,单位:cm Setting& x_SubdivisionMultiples = x.add("SubdivisionMultiples", Setting::TypeInt) = 128;//细分倍数 Setting& x_ScaleFactor = x.add("ScaleFactor", Setting::TypeFloat) = 1.0;//缩放因子 + Setting& x_MaxRange = x.add("MaxRange", Setting::TypeFloat) = 120.0; Setting& y_StepAnglemar = y.add("StepAnglemar", Setting::TypeFloat) = 1.8; Setting& y_Lead = y.add("Lead", Setting::TypeFloat) = 13.5; Setting& y_SubdivisionMultiples = y.add("SubdivisionMultiples", Setting::TypeInt) = 128; Setting& y_ScaleFactor = y.add("ScaleFactor", Setting::TypeFloat) = 0.2; + Setting& y_MaxRange = y.add("MaxRange", Setting::TypeFloat) = 120.0; // Write out the new configuration. try diff --git a/HPPA/hppaConfigFile.h b/HPPA/hppaConfigFile.h index ac6e272..f40ec22 100644 --- a/HPPA/hppaConfigFile.h +++ b/HPPA/hppaConfigFile.h @@ -16,6 +16,8 @@ #include #include +#include "utility_tc.h" + using namespace std; using namespace libconfig; @@ -35,8 +37,10 @@ public: bool getFitParams(float& fa, float& fb); bool getAutoFocusRange(int& max, int& min); - bool getXMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor); - bool getYMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor); + bool getXMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor, float& MaxRange); + bool getYMotorParm(float& StepAnglemar, float& Lead, int& SubdivisionMultiples, float& ScaleFactor, float& MaxRange); + bool setMaxRange(float maxRange, QString x_y); + bool writeConfig2File(); bool createConfigFile(); bool updateConfigFile(); diff --git a/HPPA/imageProcessor.cpp b/HPPA/imageProcessor.cpp index 4c1b6c5..6bce098 100644 --- a/HPPA/imageProcessor.cpp +++ b/HPPA/imageProcessor.cpp @@ -27,7 +27,7 @@ std::vector ImageProcessor::CHistogram(const cv::Mat img) //以防数据中有负值:当镜头盖盖上在扣除暗电流就有可能为负值 //如果mat的数据类型为CV_16UC3,当数据中有有负值时,负值表现为65535 - if (gv > 4096) + if (gv >= 4096) { ++hisnum[0]; } diff --git a/HPPA/resononImager.cpp b/HPPA/resononImager.cpp index 7ca9256..6b1f9ff 100644 --- a/HPPA/resononImager.cpp +++ b/HPPA/resononImager.cpp @@ -1,30 +1,11 @@ -#include "stdafx.h" -#include -#include -#include -#include #include "resononImager.h" -ResononImager::ResononImager() +ResononPicaLImager::ResononPicaLImager() { - m_iFrameCounter = 1; - m_bRecordControlState = true; - m_FileName2Save = "tmp_image"; - m_FileSavedCounter = 1; - - m_RgbImage = new CImage(); - - buffer = nullptr; - dark = nullptr; - white = nullptr; - - m_HasDark = false; - m_HasWhite = false; - m_bFocusControlState = false; } -ResononImager::~ResononImager() +ResononPicaLImager::~ResononPicaLImager() { if (buffer != nullptr) { @@ -35,425 +16,90 @@ ResononImager::~ResononImager() } } -CImage * ResononImager::getRgbImage() const +double ResononPicaLImager::getFramerate() { - return m_RgbImage; + return m_ResononPicaLImager.get_framerate(); } -cv::Mat * ResononImager::getMatRgbImage() const +double ResononPicaLImager::getIntegrationTime() { - return m_RgbImage->m_matRgbImage; + return m_ResononPicaLImager.get_integration_time(); } -cv::Mat * ResononImager::getMatFocusGrayImage() const +double ResononPicaLImager::getGain() { - return m_RgbImage->m_matFocusGrayImage; + return m_ResononPicaLImager.get_gain(); } -QImage ResononImager::getQImageFocusGrayImage() const +void ResononPicaLImager::setGain(const double gain) { - return *m_RgbImage->m_qimageFocusGrayImage; + m_ResononPicaLImager.set_gain(gain); } -bool ResononImager::getRecordControlState() const +void ResononPicaLImager::setFramerate(const double frames_per_second) { - return m_bRecordControlState; -} - -void ResononImager::setRecordControlState(bool RecordControlState) -{ - m_bRecordControlState = RecordControlState; -} - -int ResononImager::getFrameCounter() const -{ - return m_iFrameCounter; -} - -int ResononImager::getFocusFrameCounter() const -{ - return m_iFocusFrameCounter; -} - -void ResononImager::WriteHdr() -{ - //write an ENVI compatible header file - using namespace std; - - - FileOperation * fileOperation = new FileOperation(); - string directory = fileOperation->getDirectoryFromString(); - - string hdrPath = directory + "\\" + m_FileName2Save + "_" + std::to_string(m_FileSavedCounter) + ".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 = " << m_ResononImager.get_sample_count() << "\n"; - outfile << "bands = " << m_ResononImager.get_band_count() << "\n"; - outfile << "lines = " << m_iFrameCounter << "\n"; - outfile << "framerate = " << m_ResononImager.get_framerate() << "\n"; - outfile << "shutter = " << m_ResononImager.get_integration_time() << "\n"; - outfile << "gain = " << m_ResononImager.get_gain() << "\n"; - outfile << "wavelength = {"; - outfile << std::setprecision(5); - - int start = m_ResononImager.get_start_band(); - int end = m_ResononImager.get_end_band(); - for (int i = start; i < end - 1; i++) - { - outfile << m_ResononImager.get_wavelength_at_band(i) << ", "; - } - outfile << m_ResononImager.get_wavelength_at_band(end - 1) << "}\n"; - outfile.close(); -} - -unsigned short ResononImager::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; -} - -void ResononImager::connect_imager(int frameNumber) -{ - m_ResononImager.connect(); - set_framerate(30.0); - set_integration_time(1); - set_gain(0); - - m_ResononImager.set_spectral_bin(2); - //m_ResononImager.set_spatial_bin(2); - - set_buffer(); - m_RgbImage->SetRgbImageWidthAndHeight(getBandCount(), getSampleCount(), frameNumber); - m_iFrameNumber = frameNumber; - - emit testImagerStatus(); - - //std::cout << "------------------------------------------------------" << std::endl; -} - -void ResononImager::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); - } - - FileOperation * fileOperation = new FileOperation(); - string directory = fileOperation->getDirectoryFromString(); - string imgPath = directory + "\\" + m_FileName2Save + "_" + std::to_string(m_FileSavedCounter); - - m_fImage = fopen(imgPath.c_str(), "w+b"); - - - size_t x; - double pixelValueTmp; - - m_ResononImager.start(); - while (m_bRecordControlState) - { - m_iFrameCounter++; - - m_ResononImager.get_frame(buffer); - - //减去暗电流,应为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); - - //将rgb波段提取出来,以便在界面中显示 - m_RgbImage->FillRgbImage(buffer);//?????????????????????????????????????????????????????????????????????????????????????????????????????? - - //std::cout << "第" << m_iFrameCounter << "帧写了" << x << "个unsigned short。" << std::endl; - - //每隔1s进行一次界面图形绘制 - if (m_iFrameCounter % (int)m_ResononImager.get_framerate() == 0) - { - emit PlotSignal(); - } - - if (m_iFrameCounter >= m_iFrameNumber) - { - break; - } - - } - m_ResononImager.stop(); - - 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); -} - -void ResononImager::record_dark() -{ - std::cout << "采集暗电流!!!!!!!!!" << std::endl; - m_ResononImager.start(); - m_ResononImager.get_frame(dark); - m_ResononImager.stop(); - - m_HasDark = true; -} - -void ResononImager::record_white() -{ - std::cout << "采集暗白板!!!!!!!!!" << std::endl; - m_ResononImager.start(); - m_ResononImager.get_frame(white); - m_ResononImager.stop(); - - //白板扣暗电流 - 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; -} - -double ResononImager::get_framerate() -{ - return m_ResononImager.get_framerate(); -} - -double ResononImager::get_integration_time() -{ - return m_ResononImager.get_integration_time(); -} - -double ResononImager::get_gain() -{ - return m_ResononImager.get_gain(); -} - -void ResononImager::set_framerate(const double frames_per_second) -{ - - m_ResononImager.set_framerate(frames_per_second); + m_ResononPicaLImager.set_framerate(frames_per_second); m_RgbImage->m_iFramerate = frames_per_second; } -void ResononImager::set_integration_time(const double milliseconds) +void ResononPicaLImager::setIntegrationTime(const double milliseconds) { - m_ResononImager.set_integration_time(milliseconds); + m_ResononPicaLImager.set_integration_time(milliseconds); } -void ResononImager::set_gain(const double gain) +int ResononPicaLImager::getStartBand() { - m_ResononImager.set_gain(gain); + return m_ResononPicaLImager.get_start_band(); } -void ResononImager::set_buffer() +int ResononPicaLImager::getEndBand() { - //如果 - if (buffer != nullptr) - { - std::cout << "释放堆上内存" << std::endl; - free(buffer); - } - - m_FrameSize = m_ResononImager.get_band_count()*m_ResononImager.get_sample_count(); - //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; + return m_ResononPicaLImager.get_end_band(); } -void ResononImager::setFrameNumber(int FrameNumber) +void ResononPicaLImager::connectImager(const char* camera_sn) { - m_iFrameNumber = FrameNumber; - m_RgbImage->SetRgbImageWidthAndHeight(getBandCount(), getSampleCount(), FrameNumber); + m_ResononPicaLImager.connect(); } -double ResononImager::auto_exposure() +void ResononPicaLImager::disconnectImager() { - //第一步:先设置曝光时间为在当前帧率情况下最大 - double x = 1 / m_ResononImager.get_framerate()*1000;//获取最大毫秒曝光时间 - m_ResononImager.set_integration_time(x); - - //第二步:通过循环寻找最佳曝光时间 - m_ResononImager.start(); - - while (true) - { - m_ResononImager.get_frame(buffer); - if (GetMaxValue(buffer, m_FrameSize) >= 4095) - { - set_integration_time(get_integration_time()*0.8); - std::cout << "自动曝光-----------" << std::endl; - } - else - { - break; - } - } - - m_ResononImager.stop(); - - //std::cout << "自动曝光:" << get_integration_time() << std::endl; - - return get_integration_time(); + m_ResononPicaLImager.disconnect(); } -void ResononImager::setFocusControlState(bool FocusControlState) +void ResononPicaLImager::imagerStartCollect() { - m_bFocusControlState = FocusControlState; + m_ResononPicaLImager.start(); } -void ResononImager::setFileName2Save(string FileName) +void ResononPicaLImager::imagerStopCollect() { - m_FileName2Save = FileName; - m_FileSavedCounter = 1; + m_ResononPicaLImager.stop(); } -double ResononImager::getWavelengthAtBand(int band) +unsigned short* ResononPicaLImager::getFrame(unsigned short* buffer) { - return m_ResononImager.get_wavelength_at_band(band); + m_ResononPicaLImager.get_frame(buffer); + + return buffer; } -int ResononImager::getBandCount() +void ResononPicaLImager::setSpectraBin(int new_spectral_bin) { - return m_ResononImager.get_band_count(); + } -int ResononImager::getSampleCount() +double ResononPicaLImager::getWavelengthAtBand(int band) { - return m_ResononImager.get_sample_count(); + return m_ResononPicaLImager.get_wavelength_at_band(band); } -int ResononImager::GetImageSize(int &iWidth, int &iHeight) +int ResononPicaLImager::getBandCount() { - /*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; + return m_ResononPicaLImager.get_band_count(); } -void ResononImager::focus() +int ResononPicaLImager::getSampleCount() { - m_iFocusFrameCounter = 1; - //std::cout << "调焦-----------" << std::endl; - - double tmpFrmerate = m_ResononImager.get_framerate(); - double tmpIntegrationTime = m_ResononImager.get_integration_time(); - - - m_ResononImager.set_framerate(5); - auto_exposure(); - std::cout << "调焦获得的曝光时间为:" << m_ResononImager.get_integration_time() << std::endl; - - m_ResononImager.start(); - - //emit SpectralSignal(1); - m_bFocusControlState = true; - while (m_bFocusControlState) - { - m_ResononImager.get_frame(buffer); - //m_RgbImage->FillFocusGrayImage(buffer); - m_RgbImage->FillFocusGrayQImage(buffer); - - emit SpectralSignal(1); - - ++m_iFocusFrameCounter; - } - emit SpectralSignal(0); - - m_ResononImager.stop(); - - m_ResononImager.set_framerate(tmpFrmerate); - m_ResononImager.set_integration_time(tmpIntegrationTime); + return m_ResononPicaLImager.get_sample_count(); } diff --git a/HPPA/resononImager.h b/HPPA/resononImager.h index 511b5a8..1f45ea4 100644 --- a/HPPA/resononImager.h +++ b/HPPA/resononImager.h @@ -4,94 +4,45 @@ #include #include +#include "ImagerOperationBase.h" #include "resonon_imager_basler.h" #include "image2display.h" #include "fileOperation.h" -class ResononImager:public QObject +class ResononPicaLImager:public ImagerOperationBase { Q_OBJECT public: - ResononImager(); - ~ResononImager(); + ResononPicaLImager(); + ~ResononPicaLImager(); - Resonon::PikaBasler m_ResononImager;// - - CImage* getRgbImage() const; - cv::Mat * getMatRgbImage() const; - cv::Mat * getMatFocusGrayImage() const; - QImage getQImageFocusGrayImage() const; - - bool getRecordControlState() const; - void setRecordControlState(bool RecordControlState); - - int getFrameCounter() const; - int getFocusFrameCounter() const; - - unsigned short * buffer;//存储采集到的影像的中间变量,下一步写入到硬盘中 - - void set_buffer(); - void setFrameNumber(int FrameNumber); - double auto_exposure(); - - - void setFocusControlState(bool FocusControlState); - - void setFileName2Save(string FileName); + Resonon::PikaBasler m_ResononPicaLImager;// double getWavelengthAtBand(int band); int getBandCount(); int getSampleCount(); - - int GetImageSize(int &iWidth, int &iHeight); + double getFramerate(); + double getIntegrationTime(); + double getGain(); + void setFramerate(const double frames_per_second); + void setIntegrationTime(const double milliseconds); + void setGain(const double gain); + int getStartBand(); + int getEndBand(); + void connectImager(const char* camera_sn = NULL); + void disconnectImager(); + void imagerStartCollect(); + void imagerStopCollect(); + unsigned short* getFrame(unsigned short* buffer); + void setSpectraBin(int new_spectral_bin); protected: private: - CImage* m_RgbImage;//显示的rgb图像 - int m_iFrameNumber;//需要采集的总帧数 - int m_iFrameCounter;//记录采集的帧数 - int m_iFocusFrameCounter;//记录调焦时采集的帧数 - bool m_bRecordControlState;//采集状态;可用于执行停止采集操作 - bool m_bFocusControlState;//控制调焦结束 - - //以下两个参数用于给保存的影像文件命名 - string m_FileName2Save;//保存的影像文件名 - int m_FileSavedCounter;//保存了几个影像文件 - - unsigned short * dark;//存储暗电流 - unsigned short * white;//存储白板 - - FILE *m_fImage;//用于写入硬盘的文件对象 - int m_FrameSize;//表示一帧代表有多少个数值:m_FrameSize = m_imager.get_band_count()*m_imager.get_sample_count(); - bool m_HasDark;//当采集了暗电流之后,设置为true - bool m_HasWhite;//当采集了白板之后,设置为true - - void WriteHdr(); - unsigned short GetMaxValue(unsigned short * dark, int number); public slots: - void connect_imager(int frameNumber);//连接相机、开辟缓存 - void start_record(); - void record_dark(); - void record_white(); - void focus(); - - double get_framerate(); - double get_integration_time(); - double get_gain(); - - void set_framerate(const double frames_per_second); - void set_integration_time(const double milliseconds); - void set_gain(const double gain); signals: - void PlotSignal();//绘制影像信号 - void RecordFinishedSignal_WhenFrameNumberMeet();//采集完成信号:需要采集的总帧数(m_iFrameNumber)采集完成 - void RecordFinishedSignal_WhenFrameNumberNotMeet();//采集完成信号:需要采集的总帧数(m_iFrameNumber)没有采集完成,中途停止采集 - void SpectralSignal(int);//发射1代表正在调焦,绘制光谱,发射0表示调焦完成; - - void testImagerStatus();//表示可以测试相机连接状态:是否连接,并反映到界面上 }; #endif \ No newline at end of file diff --git a/HPPA/utility_tc.cpp b/HPPA/utility_tc.cpp new file mode 100644 index 0000000..153a037 --- /dev/null +++ b/HPPA/utility_tc.cpp @@ -0,0 +1,123 @@ +#include "utility_tc.h" +#include + +QString formatTimeStr(char * format) +{ + //鑾峰彇绯荤粺鏃堕棿 + time_t timer;//time_t灏辨槸long int 绫诲瀷 + struct tm *tblock; + timer = time(NULL);//杩斿洖绉掓暟(绮惧害涓虹)锛屼粠1970-1-1,00:00:00 鍙互褰撴垚鏁村瀷杈撳嚭鎴栫敤浜庡叾瀹冨嚱鏁 + tblock = localtime(&timer); + //printf("Local time is: %s\n", asctime(tblock)); + + //鏍煎紡鍖栨椂闂翠负闇瑕佺殑鏍煎紡 + char timeStr_tmp[256] = { 0 }; + strftime(timeStr_tmp, sizeof(timeStr_tmp), format, tblock);// + + QString timeStr2(timeStr_tmp); +// qDebug() << "time is:" << timeStr2; + + return timeStr2; +} + +QString getFileNameBaseOnTime() +{ + using namespace std; + + //鑾峰彇绯荤粺鏃堕棿 + time_t timer;//time_t灏辨槸long int 绫诲瀷 + struct tm *tblock; + timer = time(NULL);//杩斿洖绉掓暟(绮惧害涓虹)锛屼粠1970-1-1,00:00:00 鍙互褰撴垚鏁村瀷杈撳嚭鎴栫敤浜庡叾瀹冨嚱鏁 + tblock = localtime(&timer); + //printf("Local time is: %s\n", asctime(tblock)); + + //鏍煎紡鍖栨椂闂翠负闇瑕佺殑鏍煎紡 + char fileNameTmp[256] = { 0 }; + char dirNameTmp[256] = { 0 }; + strftime(fileNameTmp, sizeof(fileNameTmp), "%Y%m%d_%H%M%S", tblock); + strftime(dirNameTmp, sizeof(dirNameTmp), "%Y%m%d", tblock); + QString fileName(fileNameTmp); + QString dirName(dirNameTmp); + +// QString fileName=QString::number(tblock->tm_year+1900)+QString::number(tblock->tm_mon+1)+QString::number(tblock->tm_mday)+"_"+QString::number(tblock->tm_hour)+QString::number(tblock->tm_min);// + + //璁剧疆鏂囦欢缁濆璺緞 + QDir path("/media/nvme"); + if(!path.exists(dirName)) + { + path.mkdir(dirName); + } + path.cd(dirName); + QString absoluteFilePath=path.path()+"/"+fileName; +// printf("absoluteFilePath is: %s\n", absoluteFilePath.c_str()); +// qDebug() << "absoluteFilePath is:" << absoluteFilePath; + + return absoluteFilePath; +} + +void bubbleSort(unsigned short * a, int n) +{ +// //鎺掑簭瀹炵幇锛 +// for(int i=0;ia[j]) +// swap(a+j-1,a+j); + + //鎺掑簭瀹炵幇2 + int j,k,flag; + + flag = n; + while(flag>0) + { + k=flag; + flag=0; + for(j=1;ja[j]) + { + swap(a+j-1,a+j); + flag=j; + } + } +} + +void swap(unsigned short * a, unsigned short * b) +{ + int tmp; + + tmp=*a; + *a=*b; + *b=tmp; +} + + +bool createDir(QString fullPath) +{ + QDir dir(fullPath); + if (dir.exists()) { + return true; + } else { + bool ok = dir.mkpath(fullPath);//鍒涘缓澶氱骇鐩綍 + return ok; + } +} + +QList getFileInfo(QString file) +{ + QFileInfo fileInfo = QFileInfo(file); + + QString fileName, fileSuffix, filePath; + filePath = fileInfo.absolutePath();//缁濆璺緞 + fileName = fileInfo.fileName();//鏂囦欢鍚 + fileSuffix = fileInfo.suffix();//鏂囦欢鍚庣紑 + +// qDebug() << fileName < result; + result.append(filePath); + result.append(fileName); + result.append(fileSuffix); + + return result; +} diff --git a/HPPA/utility_tc.h b/HPPA/utility_tc.h new file mode 100644 index 0000000..0857f16 --- /dev/null +++ b/HPPA/utility_tc.h @@ -0,0 +1,23 @@ +#ifndef UTILITY_TC_H +#define UTILITY_TC_H + +#include +#include + +#include +#include + +QString getFileNameBaseOnTime(); + +QString formatTimeStr(char * format); + +//https://blog.csdn.net/MoreWindows/article/details/6657829 +void bubbleSort(unsigned short * a, int n); + +void swap(unsigned short * a, unsigned short * b); + +bool createDir(QString fullPath); + +QList getFileInfo(QString file); + +#endif // UTILITY_TC_H