You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
623 lines
15 KiB
C++
623 lines
15 KiB
C++
#include "mainwidget.h"
|
|
#include "ui_mainwidget.h"
|
|
#include <QFileDialog>
|
|
#include <QFile>
|
|
#include <QDebug>
|
|
#include <QMessageBox>
|
|
#include <QTextCodec>
|
|
#include "coutlinedetector.h"
|
|
#include <QButtonGroup>
|
|
#include <QSpinBox>
|
|
MainWidget::MainWidget(QWidget *parent)
|
|
: QWidget(parent)
|
|
, ui(new Ui::MainWidget)
|
|
, m_pSurface(nullptr)
|
|
, m_detector(nullptr)
|
|
{
|
|
|
|
|
|
ui->setupUi(this);
|
|
|
|
InitWidget();
|
|
|
|
|
|
m_detector = new COutlineDetector;
|
|
|
|
|
|
// 连接鼠标移动信号到槽函数
|
|
connect(ui->viewWidget, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(showMousePosition(QMouseEvent*)));
|
|
|
|
|
|
}
|
|
|
|
|
|
//初始化界面
|
|
void MainWidget::InitWidget(void)
|
|
{
|
|
setWindowTitle(tr("沉积相轮廓识别 Beta"));
|
|
|
|
ui->viewWidget->setStyleSheet("QWidget { border: 1px solid black; }");
|
|
|
|
ui->edit_zMin->setText("2000");
|
|
ui->edit_zMax->setText("10000");
|
|
|
|
ui->btnBlackWhite->setEnabled(false);
|
|
ui->btnExecute->setEnabled(false);
|
|
ui->btnOutputContours->setEnabled(false);
|
|
|
|
|
|
ui->sliderZMin->setRange(0,2000);
|
|
ui->sliderZMax->setRange(0,2000);
|
|
ui->sliderZMax->setValue(2000);
|
|
// ui->sliderDilateDist->setRange(0,100);
|
|
// ui->sliderDilateDist->setValue(0);
|
|
|
|
|
|
|
|
ui->labelDisp->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
|
|
|
|
|
|
|
|
InitButtons();
|
|
}
|
|
|
|
|
|
|
|
|
|
void MainWidget::InitButtons(void)
|
|
{
|
|
|
|
|
|
ui->btnOrigin->setCheckable(true);
|
|
ui->btnBlackWhite->setCheckable(true);
|
|
ui->btnExecute->setCheckable(true);
|
|
ui->btnOrigin->setChecked(true);
|
|
QButtonGroup* btnGroup = new QButtonGroup(this);
|
|
btnGroup->addButton(ui->btnOrigin,0);
|
|
btnGroup->addButton(ui->btnBlackWhite,1);
|
|
btnGroup->addButton(ui->btnExecute,2);
|
|
btnGroup->setExclusive(true);
|
|
|
|
}
|
|
|
|
|
|
MainWidget::~MainWidget()
|
|
{
|
|
if(m_pSurface)
|
|
delete m_pSurface;
|
|
|
|
if(m_detector)
|
|
delete m_detector;
|
|
|
|
delete ui;
|
|
}
|
|
|
|
|
|
|
|
void MainWidget::showMousePosition(QMouseEvent *event)
|
|
{
|
|
// 获取鼠标在绘图区域的像素位置
|
|
QPoint pos = event->pos();
|
|
// 将像素位置转换为坐标值
|
|
double x = ui->viewWidget->xAxis->pixelToCoord(pos.x());
|
|
double y = ui->viewWidget->yAxis->pixelToCoord(pos.y());
|
|
double z = 1e31;
|
|
if(nullptr != m_pSurface)
|
|
{
|
|
z = m_pSurface->Z(x,y);
|
|
if(z > 1e20)
|
|
z = 1e31;
|
|
}
|
|
|
|
|
|
QString xstr = QString::number(x,'g',8);
|
|
QString ystr = QString::number(y,'g',8);
|
|
QString zstr = QString::number(z,'g',8);
|
|
|
|
// qDebug() << x << " " << y;
|
|
// 在状态栏中显示坐标信息
|
|
if(z> 1e20)
|
|
ui->labelDisp->setText(QString("x:%1, y:%2").arg(xstr).arg(ystr));
|
|
else
|
|
ui->labelDisp->setText(QString("x:%1, y:%2\nz:%3").arg(xstr).arg(ystr).arg(zstr));
|
|
|
|
}
|
|
|
|
void MainWidget::on_btnCancel_clicked()
|
|
{
|
|
qApp->quit();
|
|
}
|
|
|
|
void MainWidget::on_btnDfg_clicked()
|
|
{
|
|
QString strFile = QFileDialog::getOpenFileName(this,
|
|
tr("打开文件"),"",tr("Dfg files(*.dfg)"));
|
|
|
|
if(strFile.isEmpty())
|
|
return;
|
|
|
|
|
|
ui->editDfg->setText(strFile);
|
|
|
|
if(!loadDfg(strFile))
|
|
{
|
|
QMessageBox::warning(this,tr("警告"),tr("所选文件无法打开"));
|
|
return;
|
|
}
|
|
|
|
|
|
ui->btnBlackWhite->setEnabled(true);
|
|
ui->btnExecute->setEnabled(true);
|
|
ui->btnOutputContours->setEnabled(false);
|
|
|
|
|
|
}
|
|
|
|
bool MainWidget::loadDfg(QString strDfg)
|
|
{
|
|
|
|
disconnect(ui->spinDilate,0,0,0);
|
|
terminateConnection(ui->edit_zMax,ui->sliderZMax);
|
|
terminateConnection(ui->edit_zMin,ui->sliderZMin);
|
|
|
|
|
|
ui->viewWidget->resetAxisRect();
|
|
|
|
|
|
if(m_pSurface)
|
|
delete m_pSurface;
|
|
m_pSurface = new GSurface;
|
|
|
|
|
|
QTextCodec *gbk = QTextCodec::codecForName("GBK");
|
|
QByteArray arr=gbk->fromUnicode(strDfg);
|
|
|
|
qApp->setOverrideCursor(Qt::BusyCursor);
|
|
|
|
if( !m_pSurface->ReadDfg(arr.data()) )
|
|
{
|
|
delete m_pSurface;
|
|
m_pSurface = nullptr;
|
|
|
|
qApp->restoreOverrideCursor();
|
|
return false;
|
|
}
|
|
|
|
|
|
m_detector->clear();
|
|
m_detector->setSurface(m_pSurface);
|
|
ui->viewWidget->resetColorScaleRange();
|
|
updateGridParas();
|
|
ui->viewWidget->m_bTransparentColormap = true;
|
|
ui->viewWidget->setType(ViewWidget::colorfulmap);
|
|
if(m_pSurface)
|
|
ui->viewWidget->setGrid(m_pSurface,true);
|
|
|
|
|
|
|
|
ui->viewWidget->m_bTransparentColormap = false;
|
|
|
|
QTimer::singleShot(5,[this]{
|
|
if(m_pSurface)
|
|
|
|
ui->viewWidget->setGrid(m_pSurface,true);
|
|
|
|
});
|
|
|
|
qApp->restoreOverrideCursor();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MainWidget::writeContours(QString strFile)
|
|
{
|
|
QTextCodec *gbk = QTextCodec::codecForName("GBK");
|
|
QByteArray arr=gbk->fromUnicode(strFile);
|
|
|
|
m_detector->setContourMinArea(ui->edit_minArea->text().toFloat());
|
|
m_detector->setContourSmoothTimes(ui->edit_smoothTimes->text().toUInt());
|
|
|
|
|
|
//生成沉积相轮廓
|
|
m_detector->CreateFaciesContours();
|
|
vector<vector<Point2f> > dstvec;
|
|
m_detector->multiContourToRealCoords(m_detector->GetFaciesContours(),
|
|
dstvec, 0);
|
|
|
|
return m_detector->WriteContours(dstvec,arr.data());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//构建edit 和 slider的信号槽
|
|
void MainWidget::buildConnection(QLineEdit* edit, QSlider* slider)
|
|
{
|
|
|
|
connect(edit,&QLineEdit::editingFinished,[=]{
|
|
slider->setValue(qRound(edit->text().toFloat()));
|
|
if(ui->btnExecute->isChecked())
|
|
on_btnExecute_clicked();
|
|
else if(ui->btnBlackWhite->isChecked())
|
|
on_btnBlackWhite_clicked();
|
|
|
|
} );
|
|
|
|
|
|
connect(slider,&QSlider::valueChanged,[=]{
|
|
float valedit = edit->text().toFloat();
|
|
float valslider = slider->value();
|
|
if(fabs(valedit-valslider) > 1)
|
|
edit->setText(QString::number(valslider));
|
|
|
|
});
|
|
|
|
connect(slider,&QSlider::sliderReleased,[=]{
|
|
if(ui->btnExecute->isChecked())
|
|
on_btnExecute_clicked();
|
|
// else if(ui->btnBlackWhite->isChecked())
|
|
// on_btnBlackWhite_clicked();
|
|
});
|
|
|
|
connect(slider,&QSlider::sliderMoved, [=]{
|
|
if(ui->btnBlackWhite->isChecked())
|
|
on_btnBlackWhite_clicked();
|
|
});
|
|
|
|
|
|
|
|
}
|
|
//解除信号槽
|
|
void MainWidget::terminateConnection(QLineEdit* edit, QSlider* slider)
|
|
{
|
|
disconnect(edit,0,0,0);
|
|
disconnect(slider,0,0,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWidget::updateGridParas(void)
|
|
{
|
|
|
|
disconnect(ui->spinDilate,0,0,0);
|
|
disconnect(ui->edit_minArea,0,0,0);
|
|
disconnect(ui->edit_smoothTimes,0,0,0);
|
|
terminateConnection(ui->edit_zMax,ui->sliderZMax);
|
|
terminateConnection(ui->edit_zMin,ui->sliderZMin);
|
|
|
|
|
|
|
|
if(!m_pSurface)
|
|
return;
|
|
|
|
int xnum = m_pSurface->XNum();
|
|
int ynum = m_pSurface->YNum();
|
|
float deltx = m_pSurface->DeltX();
|
|
float delty = m_pSurface->DeltY();
|
|
double* range = m_pSurface->GetRange();
|
|
float zmin = range[0];
|
|
float zmax = range[1];
|
|
|
|
|
|
|
|
|
|
ui->sliderZMax->setRange(zmin,zmax);
|
|
ui->sliderZMin->setRange(zmin,zmax);
|
|
ui->sliderZMin->setValue(int(zmin+zmax)/2);
|
|
ui->sliderZMax->setValue(zmax);
|
|
|
|
|
|
ui->edit_zMin->setText(QString::number(int(zmin+zmax)/2));
|
|
ui->edit_zMax->setText(QString::number(int(zmax)));
|
|
|
|
|
|
int dt = ceil(max(deltx, delty));
|
|
ui->spinDilate->setRange(0,min(xnum,ynum)/4);
|
|
ui->spinDilate->setValue(2);
|
|
ui->spinDilate->setSingleStep(1);
|
|
|
|
|
|
ui->label_colNum->setText(QString::number( xnum));
|
|
ui->label_rowNum->setText(QString::number(ynum));
|
|
ui->label_deltX->setText(QString::number(deltx,'g',6));
|
|
ui->label_deltY->setText(QString::number(deltx,'g',6));
|
|
ui->label_zMin->setText(QString::number(zmin,'g',6));
|
|
ui->label_zMax->setText(QString::number(zmax,'g',6));
|
|
|
|
// ui->edit_dilateDist_2->setText(QString::number(std::max(deltx,delty)*2,'g',6) );
|
|
|
|
|
|
|
|
buildConnection(ui->edit_zMax,ui->sliderZMax);
|
|
buildConnection(ui->edit_zMin,ui->sliderZMin);
|
|
//buildConnection(ui->edit_dilateDist_2,ui->sliderDilateDist);
|
|
|
|
//平滑次数信号槽
|
|
|
|
connect(ui->edit_smoothTimes, &QLineEdit::editingFinished,[this]{
|
|
if(ui->btnExecute->isChecked())
|
|
{
|
|
|
|
// QTimer::singleShot(100,[this]{
|
|
on_btnExecute_clicked();
|
|
// });
|
|
|
|
}
|
|
});
|
|
|
|
connect(ui->edit_minArea, &QLineEdit::editingFinished,[this]{
|
|
if(ui->btnExecute->isChecked())
|
|
{
|
|
|
|
// QTimer::singleShot(100,[this]{
|
|
on_btnExecute_clicked();
|
|
// });
|
|
|
|
}
|
|
});
|
|
|
|
|
|
//最小面积信号槽
|
|
connect(ui->spinDilate, QOverload<int>::of(&QSpinBox::valueChanged),[this]{
|
|
if(ui->btnExecute->isChecked())
|
|
{
|
|
|
|
QTimer::singleShot(100,[this]{
|
|
on_btnExecute_clicked();
|
|
});
|
|
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
// connect(ui->spinDilate, &QSpinBox::editingFinished,[this]{
|
|
// if(ui->btnExecute->isChecked())
|
|
// on_btnExecute_clicked();
|
|
// });
|
|
}
|
|
|
|
|
|
void MainWidget::on_btnBlackWhite_clicked()
|
|
{
|
|
ui->viewWidget->saveCurrentAxisRect();
|
|
|
|
cv::Mat mat;
|
|
float zupper = ui->edit_zMax->text().toFloat();
|
|
float zlower = ui->edit_zMin->text().toFloat();
|
|
COutlineDetector::convertSurfaceToMat(m_pSurface,zlower,zupper,mat);
|
|
|
|
qApp->setOverrideCursor(Qt::BusyCursor);
|
|
GSurface& surf =m_surfBlackWhite;
|
|
if( nullptr == m_pSurface || ! COutlineDetector::convertMatToSurface(mat,m_pSurface->X(0),
|
|
m_pSurface->Y(0),m_pSurface->DeltX(),m_pSurface->DeltY(),&surf) )
|
|
{
|
|
qApp->restoreOverrideCursor();
|
|
return;
|
|
}
|
|
|
|
ui->viewWidget->setType(ViewWidget::graymap);
|
|
ui->viewWidget->setGrid(&surf,true);
|
|
|
|
// QImage img;
|
|
// if(! COutlineDetector::ConvertMatToQImage(mat,img) )
|
|
// return;
|
|
|
|
// img = img.mirrored(false,true);
|
|
|
|
// ui->viewWidget->setImage(img,true);
|
|
|
|
|
|
qApp->restoreOverrideCursor();
|
|
|
|
}
|
|
|
|
void MainWidget::on_btnExecute_clicked()
|
|
{
|
|
|
|
|
|
|
|
if(nullptr == m_pSurface)
|
|
return;
|
|
|
|
|
|
|
|
qApp->setOverrideCursor(Qt::WaitCursor);
|
|
|
|
|
|
ui->viewWidget->saveCurrentAxisRect();
|
|
|
|
//形态学处理图像,生成初始等值线
|
|
ProcessImageAndCreateOriginalContours();
|
|
|
|
|
|
// //begin test
|
|
// // //显示形态学处理后图像的黑白图,暂时不用
|
|
// cv::Mat mat = m_detector->getResultMat();
|
|
// cv::imshow("facies",mat);
|
|
// //end test
|
|
|
|
|
|
// //BEGIN TEST
|
|
|
|
// qApp->restoreOverrideCursor();
|
|
// ui->btnOutputContours->setEnabled(true);
|
|
// return;
|
|
// //END TEST
|
|
|
|
|
|
ShowOriginalContours();
|
|
|
|
|
|
// float zupper = ui->edit_zMax->text().toFloat();
|
|
// float zlower = ui->edit_zMin->text().toFloat();
|
|
// int nIters = ceil(ui->edit_dilateDist_2->text().toFloat() / std::min(m_pSurface->DeltX(),m_pSurface->DeltY()));
|
|
|
|
|
|
// COutlineDetector* detector = m_detector;
|
|
// detector->setSurface(m_pSurface,zlower,zupper,nIters);
|
|
|
|
// m_detector->setContourMinArea(ui->edit_minArea->text().toFloat());
|
|
// m_detector->setContourSmoothTimes(ui->edit_smoothTimes->text().toUInt());
|
|
|
|
|
|
// detector->ProcessImage();
|
|
|
|
|
|
// cv::Mat mat = detector->getResultMat();
|
|
|
|
|
|
// GSurface surf;
|
|
// if( nullptr == m_pSurface || ! COutlineDetector::convertMatToSurface(mat,m_pSurface->X(0),
|
|
// m_pSurface->Y(0),m_pSurface->DeltX(),m_pSurface->DeltY(),&surf) )
|
|
// return;
|
|
|
|
// ui->viewWidget->setType(ViewWidget::gray);
|
|
// ui->viewWidget->setGrid(&surf);
|
|
// ui->btnOutputContours->setEnabled(true);
|
|
|
|
//// QImage img;
|
|
//// if(! COutlineDetector::ConvertMatToQImage(mat,img) )
|
|
//// {
|
|
//// qApp->restoreOverrideCursor();
|
|
//// return;
|
|
//// }
|
|
//// img = img.mirrored(false,true);
|
|
|
|
// // ui->viewWidget->setImage(img,true);
|
|
|
|
|
|
|
|
|
|
qApp->restoreOverrideCursor();
|
|
ui->btnOutputContours->setEnabled(true);
|
|
}
|
|
|
|
void MainWidget::on_btnOutputContours_clicked()
|
|
{
|
|
QString strFile = QFileDialog::getSaveFileName(this,
|
|
tr("保存文件"),"",tr("Dfd files(*.dfd)"));
|
|
|
|
if(strFile.isEmpty())
|
|
return;
|
|
|
|
qApp->setOverrideCursor(Qt::WaitCursor);
|
|
|
|
bool rst = writeContours(strFile);
|
|
qApp->restoreOverrideCursor();
|
|
if(!rst)
|
|
{
|
|
QMessageBox::warning(this,"Warnning",tr("输出轮廓线失败!"));
|
|
}else
|
|
QMessageBox::warning(this,"Result",tr("输出轮廓线完成!"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
void MainWidget::on_btnOrigin_clicked()
|
|
{
|
|
ui->viewWidget->saveCurrentAxisRect();
|
|
if(m_pSurface)
|
|
{
|
|
ui->viewWidget->setType(ViewWidget::colorfulmap);
|
|
ui->viewWidget->setGrid(m_pSurface,true);
|
|
}
|
|
}
|
|
|
|
|
|
//绘制m_detector中的original轮廓线
|
|
void MainWidget::ShowOriginalContours(void)
|
|
{
|
|
ui->viewWidget->setType(ViewWidget::colorfulmap_contours);
|
|
ui->viewWidget->setGrid(m_pSurface,false);
|
|
|
|
float minArea = ui->edit_minArea->text().toFloat();
|
|
if(minArea < 1e-4)
|
|
minArea = 1e-4;
|
|
|
|
vector<vector<Point2f>> tmpContours ;//= m_detector->GetOriginalContours();
|
|
|
|
m_detector->multiContourToRealCoords(m_detector->GetOriginalContours(),tmpContours,0);
|
|
|
|
vector<vector<Point2f>> drawingcontours;
|
|
drawingcontours.reserve(tmpContours.size() );
|
|
|
|
for(auto& p:tmpContours)
|
|
{
|
|
if(contourArea(p) < minArea)
|
|
continue;
|
|
drawingcontours.push_back(p);
|
|
}
|
|
|
|
|
|
|
|
|
|
// vector<vector<Point2f>> tmp2;
|
|
// for(int i = 0; i < 1; i ++ )
|
|
// tmp2.push_back(tmpContours[i]);
|
|
|
|
|
|
// tmpContours.assign(tmp2.begin(),tmp2.end() );
|
|
// m_detector->WriteContours(tmp2,"d:/tmp2.dfd");
|
|
|
|
|
|
ui->viewWidget->setContours(drawingcontours);
|
|
ui->viewWidget->updateDraw();
|
|
}
|
|
|
|
//进行形态学处理并生成初始轮廓线
|
|
void MainWidget::ProcessImageAndCreateOriginalContours()
|
|
{
|
|
float zupper = ui->edit_zMax->text().toFloat();
|
|
float zlower = ui->edit_zMin->text().toFloat();
|
|
// int nIters = ceil(ui->edit_dilateDist_2->text().toFloat() / std::min(m_pSurface->DeltX(),m_pSurface->DeltY()));
|
|
int nIters = ui->spinDilate->value();
|
|
|
|
// qDebug() << "iters = " << nIters;
|
|
|
|
COutlineDetector* detector = m_detector;
|
|
detector->setSurface(m_pSurface,zlower,zupper,nIters);
|
|
|
|
m_detector->setContourMinArea(ui->edit_minArea->text().toFloat());
|
|
m_detector->setContourSmoothTimes(ui->edit_smoothTimes->text().toUInt());
|
|
|
|
|
|
detector->ProcessImage();
|
|
|
|
// //显示形态学处理后图像的黑白图,暂时不用
|
|
// cv::Mat mat = detector->getResultMat();
|
|
|
|
|
|
|
|
|
|
// GSurface surf;
|
|
// if( nullptr == m_pSurface || ! COutlineDetector::convertMatToSurface(mat,m_pSurface->X(0),
|
|
// m_pSurface->Y(0),m_pSurface->DeltX(),m_pSurface->DeltY(),&surf) )
|
|
// return;
|
|
|
|
// ui->viewWidget->setType(ViewWidget::graymap);
|
|
// ui->viewWidget->setGrid(&surf,true);
|
|
// ui->btnOutputContours->setEnabled(true);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MainWidget::on_btnZoomAll_clicked()
|
|
{
|
|
ui->viewWidget->resetAxisRect();
|
|
ui->viewWidget->refreshAxis();
|
|
}
|