#include "mainwindow.h" #include "ui_mainwindow.h" #include "QDir" #include "QFileDialog" #include "QDebug" #include "qsqlquery.h" #include "qmessagebox.h" #include "qsqlerror.h" #include "qitemselectionmodel.h" #include //#include "faceinputdialog.h" #include "inputfilesprocessdialog.h" #include "resetmodelprocessdialog.h" #include #include #include #include //#include "Common/CStruct.h" #include using namespace std::chrono; ////////////////////////////////// const QString gcrop_prefix("crop_"); Config_Paramter gparamters; std::string gmodelpath; ///////////////////////////////////// MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { m_currenttab = -1; ui->setupUi(this); QIntValidator * vfdminfacesize = new QIntValidator(20, 1000); ui->fdminfacesize->setValidator(vfdminfacesize); QDoubleValidator *vfdthreshold = new QDoubleValidator(0.0,1.0, 2); ui->fdthreshold->setValidator(vfdthreshold); QDoubleValidator *vantispoofclarity = new QDoubleValidator(0.0,1.0, 2); ui->antispoofclarity->setValidator(vantispoofclarity); QDoubleValidator *vantispoofreality = new QDoubleValidator(0.0,1.0, 2); ui->antispoofreality->setValidator(vantispoofreality); QDoubleValidator *vyawhigh = new QDoubleValidator(0.0,90, 2); ui->yawhighthreshold->setValidator(vyawhigh); QDoubleValidator *vyawlow = new QDoubleValidator(0.0,90, 2); ui->yawlowthreshold->setValidator(vyawlow); QDoubleValidator *vpitchlow = new QDoubleValidator(0.0,90, 2); ui->pitchlowthreshold->setValidator(vpitchlow); QDoubleValidator *vpitchhigh = new QDoubleValidator(0.0,90, 2); ui->pitchhighthreshold->setValidator(vpitchhigh); QDoubleValidator *vfrthreshold = new QDoubleValidator(0.0,1.0, 2); ui->fr_threshold->setValidator(vfrthreshold); gparamters.MinFaceSize = 100; gparamters.Fd_Threshold = 0.80; gparamters.VideoWidth = 400; gparamters.VideoHeight = 400; gparamters.AntiSpoofClarity = 0.30; gparamters.AntiSpoofReality = 0.80; gparamters.PitchLowThreshold = 20; gparamters.PitchHighThreshold = 10; gparamters.YawLowThreshold = 20; gparamters.YawHighThreshold = 10; gparamters.Fr_Threshold = 0.6; gparamters.Fr_ModelPath = "face_recognizer.csta"; m_type.type = 0; m_type.filename = ""; m_type.title = "Open Camera 0"; ui->recognize_label->setText(m_type.title); int width = this->width(); int height = this->height(); this->setFixedSize(width, height); ui->db_editpicture->setStyleSheet("border-image:url(:/new/prefix1/default.png)"); ui->db_editcrop->setStyleSheet("border-image:url(:/new/prefix1/default.png)"); ///////////////////////// m_database = QSqlDatabase::addDatabase("QSQLITE"); QString exepath = QCoreApplication::applicationDirPath(); QString strdb = exepath + /*QDir::separator()*/ + "/seetaface_demo.db"; m_image_tmp_path = exepath + /*QDir::separator()*/ + "/tmp/";// + QDir::separator(); m_image_path = exepath + /*QDir::separator()*/ + "/images/";// + QDir::separator(); //m_model_path = exepath + /*QDir::separator()*/ + "/models/";// + QDir::separator(); gmodelpath = (exepath + /*QDir::separator()*/ + "/models/"/* + QDir::separator()*/).toStdString(); QDir dir; dir.mkpath(m_image_tmp_path); dir.mkpath(m_image_path); m_database.setDatabaseName(strdb); if(!m_database.open()) { QMessageBox::critical(NULL, "critical", tr("open database failed, exited!"), QMessageBox::Yes); exit(-1); } QStringList tables = m_database.tables(); m_table = "face_tab"; m_config_table = "setting_tab";//"paramter_tab"; bool bfind = false; bool bconfigfind = false; int i =0; for( i=0; ifdminfacesize->setText(QString::number(gparamters.MinFaceSize)); ui->fdthreshold->setText(QString::number(gparamters.Fd_Threshold)); ui->antispoofclarity->setText(QString::number(gparamters.AntiSpoofClarity)); ui->antispoofreality->setText(QString::number(gparamters.AntiSpoofReality)); ui->yawlowthreshold->setText(QString::number(gparamters.YawLowThreshold)); ui->yawhighthreshold->setText(QString::number(gparamters.YawHighThreshold)); ui->pitchlowthreshold->setText(QString::number(gparamters.PitchLowThreshold)); ui->pitchhighthreshold->setText(QString::number(gparamters.PitchHighThreshold)); ui->fr_threshold->setText(QString::number(gparamters.Fr_Threshold)); ui->fr_modelpath->setText(gparamters.Fr_ModelPath); qDebug() << "create config table ok!"; } ui->dbtableview->setSelectionBehavior(QAbstractItemView::SelectRows); ui->dbtableview->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->dbtableview->verticalHeader()->setDefaultSectionSize(80); ui->dbtableview->verticalHeader()->hide(); connect(ui->dbtableview, SIGNAL(clicked(QModelIndex)), this, SLOT(showfaceinfo())); m_model = new QStandardItemModel(this); QStringList columsTitles; columsTitles << "ID" << "Name" << "Image" << /*"edit" << */" "; m_model->setHorizontalHeaderLabels(columsTitles); ui->dbtableview->setModel(m_model); ui->dbtableview->setColumnWidth(0, 120); ui->dbtableview->setColumnWidth(1, 200); ui->dbtableview->setColumnWidth(2, 104); ui->dbtableview->setColumnWidth(3, 100); //ui->dbtableview->setColumnWidth(4, 100); getdatas(); /// /////////////////////////// gparamters.VideoWidth = ui->previewlabel->width(); gparamters.VideoHeight = ui->previewlabel->height(); if(bconfigfind) { //fd_minfacesize, fd_threshold, antispoof_clarity, antispoof_reality, qa_yawlow, qa_yawhigh, qa_pitchlow, qa_pitchhigh QSqlQuery q("select * from " + m_config_table); while(q.next()) { gparamters.MinFaceSize = q.value("fd_minfacesize").toInt(); ui->fdminfacesize->setText(QString::number(q.value("fd_minfacesize").toInt())); gparamters.Fd_Threshold = q.value("fd_threshold").toFloat(); ui->fdthreshold->setText(QString::number(q.value("fd_threshold").toFloat())); gparamters.AntiSpoofClarity = q.value("antispoof_clarity").toFloat(); ui->antispoofclarity->setText(QString::number(q.value("antispoof_clarity").toFloat())); gparamters.AntiSpoofReality = q.value("antispoof_reality").toFloat(); ui->antispoofreality->setText(QString::number(q.value("antispoof_reality").toFloat())); gparamters.YawLowThreshold = q.value("qa_yawlow").toFloat(); ui->yawlowthreshold ->setText(QString::number(q.value("qa_yawlow").toFloat())); gparamters.YawHighThreshold = q.value("qa_yawhigh").toFloat(); ui->yawhighthreshold ->setText(QString::number(q.value("qa_yawhigh").toFloat())); gparamters.PitchLowThreshold = q.value("qa_pitchlow").toFloat(); ui->pitchlowthreshold ->setText(QString::number(q.value("qa_pitchlow").toFloat())); gparamters.PitchHighThreshold = q.value("qa_pitchhigh").toFloat(); ui->pitchhighthreshold ->setText(QString::number(q.value("qa_pitchhigh").toFloat())); gparamters.Fr_Threshold = q.value("fr_threshold").toFloat(); gparamters.Fr_ModelPath = q.value("fr_modelpath").toString(); ui->fr_threshold->setText(QString::number(gparamters.Fr_Threshold)); ui->fr_modelpath->setText(gparamters.Fr_ModelPath); } } //////////////////////////// ui->previewtableview->setSelectionBehavior(QAbstractItemView::SelectRows); ui->previewtableview->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->previewtableview->verticalHeader()->setDefaultSectionSize(80); ui->previewtableview->verticalHeader()->hide(); //connect(ui->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(showfaceinfo())); m_videomodel = new QStandardItemModel(this); columsTitles.clear(); columsTitles << "Name" << "Score" << "Gallery" << "Snapshot" << "PID"; m_videomodel->setHorizontalHeaderLabels(columsTitles); ui->previewtableview->setModel(m_videomodel); ui->previewtableview->setColumnWidth(0, 140); ui->previewtableview->setColumnWidth(1, 80); ui->previewtableview->setColumnWidth(2, 84); ui->previewtableview->setColumnWidth(3, 84); ui->previewtableview->setColumnWidth(4, 2); ui->previewtableview->hideColumn(4); ///////////////////////// m_videothread = new VideoCaptureThread(&m_datalst, ui->previewlabel->width(), ui->previewlabel->height()); m_videothread->setparamter(); //m_videothread->setMinFaceSize(ui->fdminfacesize->text().toInt()); connect(m_videothread, SIGNAL(sigUpdateUI(const QImage &)), this, SLOT(onupdateui(const QImage &))); connect(m_videothread, SIGNAL(sigEnd(int)), this, SLOT(onvideothreadend(int))); connect(m_videothread->m_workthread, SIGNAL(sigRecognize(int, const QString &, const QString &, float, const QImage &, const QRect &)), this, SLOT(onrecognize(int, const QString &, const QString &, float, const QImage &, const QRect &))); //m_videothread->start(); m_inputfilesthread = new InputFilesThread(m_videothread, m_image_path, m_image_tmp_path); m_resetmodelthread = new ResetModelThread( m_image_path, m_image_tmp_path); connect(m_inputfilesthread, SIGNAL(sigInputFilesUpdateUI(std::vector*)), this, SLOT(oninputfilesupdateui(std::vector *)), Qt::BlockingQueuedConnection); ui->dbsavebtn->setEnabled(true); ui->previewrunbtn->setEnabled(true); ui->previewstopbtn->setEnabled(false); //ui->pushButton_6->setEnabled(false); /////////////////////// /////////////////////// //ui->label->setStyleSheet("QLabel{background-color:rgb(255,255,255);}"); //ui->label->setStyleSheet("border-image:url(:/new/prefix1/white.png)"); int a = ui->previewlabel->width(); int b = ui->previewlabel->height(); QImage image(":/new/prefix1/white.png"); QImage ime = image.scaled(a,b); ui->previewlabel->setPixmap(QPixmap::fromImage(ime)); ui->tabWidget->setCurrentIndex(0); m_currenttab = ui->tabWidget->currentIndex(); if(m_model->rowCount() > 0) { ui->dbtableview->scrollToBottom(); ui->dbtableview->selectRow(m_model->rowCount() - 1); emit ui->dbtableview->clicked(m_model->index(m_model->rowCount() - 1, 1)); } } MainWindow::~MainWindow() { delete ui; cleardata(); } void MainWindow::cleardata() { std::map::iterator iter = m_datalst.begin(); for(; iter != m_datalst.end(); ++iter) { if(iter->second) { delete iter->second; iter->second = NULL; } } m_datalst.clear(); } void MainWindow::getdatas() { int i = 0; QSqlQuery q("select * from " + m_table + " order by id asc"); while(q.next()) { //qDebug() << q.value("id").toInt() << "-----" << q.value("name").toString() << "----" << q.value("image_path").toString(); QByteArray data1 = q.value("feature_data").toByteArray(); float * ptr = (float *)data1.data(); //qDebug() << ptr[0] << "," << ptr[1] << "," << ptr[2] << "," << ptr[3] ; ////////////////////////////////////////////////// m_model->setItem(i, 0, new QStandardItem(QString::number(q.value("id").toInt()))); m_model->setItem(i, 1, new QStandardItem(q.value("name").toString())); // m_model->setItem(i, 2, new QStandardItem(q.value("image_path").toString())); QLabel *label = new QLabel(""); label->setFixedSize(100,80); label->setStyleSheet("border-image:url(" + m_image_path + q.value("image_path").toString() + ")"); ui->dbtableview->setIndexWidget(m_model->index(m_model->rowCount() - 1, 2), label); /* QPushButton *button = new QPushButton("edit"); button->setProperty("id", q.value("id").toInt()); button->setFixedSize(80, 40); connect(button, SIGNAL(clicked()), this, SLOT(editrecord())); ui->dbtableview->setIndexWidget(m_model->index(m_model->rowCount() - 1, 3), button); */ QPushButton *button2 = new QPushButton("delete"); button2->setProperty("id", q.value("id").toInt()); button2->setFixedSize(80, 40); connect(button2, SIGNAL(clicked()), this, SLOT(deleterecord())); QWidget *widget = new QWidget(); QHBoxLayout *layout = new QHBoxLayout; layout->addStretch(); layout->addWidget(button2); layout->addStretch(); widget->setLayout(layout); ui->dbtableview->setIndexWidget(m_model->index(m_model->rowCount() - 1, 3), widget); //ui->dbtableview->setIndexWidget(m_model->index(m_model->rowCount() - 1, 3), button2); DataInfo * info = new DataInfo; info->id = q.value("id").toInt(); info->name = q.value("name").toString(); info->image_path = q.value("image_path").toString(); memcpy(info->features, ptr, 1024 * sizeof(float)); info->x = q.value("facex").toInt(); info->y = q.value("facey").toInt(); info->width = q.value("facewidth").toInt(); info->height = q.value("faceheight").toInt(); m_datalst.insert(std::map::value_type(info->id, info)); i++; } } void MainWindow::editrecord() { //QPushButton *button = (QPushButton *)sender(); //qDebug() << button->property("id").toInt() << ", edit"; } void MainWindow::deleterecord() { QPushButton *button = (QPushButton *)sender(); qDebug() << button->property("id").toInt() << ",del"; QMessageBox::StandardButton reply = QMessageBox::question(NULL, "delete", tr("Are you sure delete this record?"), QMessageBox::Yes | QMessageBox::No); if(reply == QMessageBox::No) return; QModelIndex modelindex = ui->dbtableview->indexAt(button->pos()); int id = button->property("id").toInt(); QStandardItemModel * model = (QStandardItemModel *)ui->dbtableview->model(); QSqlQuery query("delete from " + m_table + " where id=" + QString::number(id)); //qDebug() << "delete from " + m_table + " where id=" + QString::number(id); if(!query.exec()) { QMessageBox::warning(NULL, "warning", tr("delete this record failed!"), QMessageBox::Yes); return; } int nrows = modelindex.row(); model->removeRow(modelindex.row()); std::map::iterator iter = m_datalst.find(id); if(iter != m_datalst.end()) { QFile file(m_image_path + iter->second->image_path); file.remove(); delete iter->second; m_datalst.erase(iter); } if(m_model->rowCount() > 0) { nrows--; if(nrows < 0) { nrows = 0; } //qDebug() << "delete------------row:" << nrows; ui->dbtableview->selectRow(nrows); emit ui->dbtableview->clicked(m_model->index(nrows, 1)); }else { ui->db_editname->setText(""); ui->db_editid->setText(""); ui->db_editpicture->setStyleSheet("border-image:url(:/new/prefix1/default.png)"); ui->db_editcrop->setStyleSheet("border-image:url(:/new/prefix1/default.png)"); } } void MainWindow::showfaceinfo() { int row = ui->dbtableview->currentIndex().row(); //qDebug() << "showfaceinfo:" << row ; if(row >= 0) { QModelIndex index = m_model->index(row, 0); int id = ui->db_editid->text().toInt(); int curid = m_model->data(index).toInt(); if(id == curid) return; ui->db_editid->setText(QString::number(m_model->data(index).toInt())); std::map::iterator iter = m_datalst.find(m_model->data(index).toInt()); if(iter == m_datalst.end()) return; index = m_model->index(row, 1); ui->db_editname->setText(m_model->data(index).toString()); QString strimage = iter->second->image_path; //qDebug() << "showfaceinfo:" << strimage; ui->db_editpicture->setStyleSheet("border-image:url(" + m_image_path + strimage + ")"); //qDebug() << "showfaceinfo:" << strimage; ui->db_editcrop->setStyleSheet("border-image:url(" + m_image_path + gcrop_prefix + strimage + ")"); iter = m_datalst.find(id); if(iter == m_datalst.end()) return; QFile::remove(m_image_tmp_path + iter->second->image_path); } } void MainWindow::onrecognize(int pid, const QString & name, const QString & imagepath, float score, const QImage &image, const QRect &rc) { int nrows = m_videomodel->rowCount(); if(nrows > 1000) { ui->previewtableview->setUpdatesEnabled(false); m_videomodel->removeRows(0, 200); ui->previewtableview->setUpdatesEnabled(true); } nrows = m_videomodel->rowCount(); int i = 0; for(; iitem(i, 4)->text().toInt() == pid) { break; } } nrows = i; m_videomodel->setItem(nrows, 0, new QStandardItem(name)); //m_videomodel->setItem(nrows, 1, new QStandardItem(QString::number(score, 'f', 3))); QLabel *label = new QLabel(""); label->setFixedSize(80,80); if(name.isEmpty()) { m_videomodel->setItem(nrows, 1, new QStandardItem("")); label->setText(imagepath); }else { m_videomodel->setItem(nrows, 1, new QStandardItem(QString::number(score, 'f', 3))); //QLabel *label = new QLabel(""); //qDebug() << "rows:" << nrows << ",imagepath:" << imagepath << "," << m_image_path + gcrop_prefix + imagepath ; //label->setFixedSize(80,80); QImage srcimage; srcimage.load( m_image_path + imagepath); srcimage = srcimage.copy(rc.x(),rc.y(),rc.width(),rc.height()); srcimage = srcimage.scaled(80,80); label->setPixmap(QPixmap::fromImage(srcimage)); //label->setStyleSheet("border-image:url(" + m_image_path + gcrop_prefix + imagepath + ")"); //ui->previewtableview->setIndexWidget(m_videomodel->index(nrows, 2), label); } ui->previewtableview->setIndexWidget(m_videomodel->index(nrows, 2), label); /* QLabel *label = new QLabel(""); qDebug() << "rows:" << nrows << ",imagepath:" << imagepath << "," << m_image_path + gcrop_prefix + imagepath ; label->setFixedSize(80,80); QImage srcimage; srcimage.load( m_image_path + imagepath); srcimage = srcimage.copy(rc.x(),rc.y(),rc.width(),rc.height()); srcimage = srcimage.scaled(80,80); label->setPixmap(QPixmap::fromImage(srcimage)); //label->setStyleSheet("border-image:url(" + m_image_path + gcrop_prefix + imagepath + ")"); ui->previewtableview->setIndexWidget(m_videomodel->index(nrows, 2), label); */ QLabel *label2 = new QLabel(""); label2->setFixedSize(80,80); QImage img = image.scaled(80,80); label2->setPixmap(QPixmap::fromImage(img)); //label2->setStyleSheet("border-image:url(" + m_image_path + gcrop_prefix + imagepath + ")"); ui->previewtableview->setIndexWidget(m_videomodel->index(nrows, 3), label2); m_videomodel->setItem(nrows, 4, new QStandardItem(QString::number(pid))); ui->previewtableview->scrollToBottom(); } void MainWindow::onupdateui(const QImage & image) { int a = ui->previewlabel->width(); int b = ui->previewlabel->height(); QImage ime = image.scaled(a,b); ui->previewlabel->setPixmap(QPixmap::fromImage(ime)); ui->previewlabel->show(); } void MainWindow::onvideothreadend(int value) { qDebug() << "onvideothreadend:" << value; //ui->label->setStyleSheet("border-image:url(:/new/prefix1/white.png)"); if(m_type.type != 2) { int a = ui->previewlabel->width(); int b = ui->previewlabel->height(); QImage image(":/new/prefix1/white.png"); QImage ime = image.scaled(a,b); ui->previewlabel->setPixmap(QPixmap::fromImage(ime)); ui->previewlabel->show(); } ui->previewrunbtn->setEnabled(true); ui->previewstopbtn->setEnabled(false); } void MainWindow::on_dbsavebtn_clicked() { //input image to database //phuckDlg *dialog = new phuckDlg(this); //dialog->setModal(true); //dialog->show(); //qDebug() << "----begin---update"; if(ui->db_editname->text().isEmpty()) { QMessageBox::critical(NULL, "critical", tr("name is empty!"), QMessageBox::Yes); return; } if(ui->db_editname->text().length() > 64) { QMessageBox::critical(NULL, "critical", tr("name length is more than 64!"), QMessageBox::Yes); return; } int index = 1; index = ui->db_editid->text().toInt(); //qDebug() << "----begin---update---index:" << index; std::map::iterator iter = m_datalst.find(index); if(iter == m_datalst.end()) { return; } QString str = m_image_tmp_path + iter->second->image_path; QFileInfo fileinfo(str); bool imageupdate = false; float features[1024]; SeetaRect rect; if(fileinfo.isFile()) { //imageupdate = true; QString cropfile = m_image_tmp_path + gcrop_prefix + iter->second->image_path; float features[1024]; int nret = m_videothread->checkimage(str, cropfile, features, rect); QString strerror; if(nret == -2) { strerror = "do not find face!"; }else if(nret == -1) { strerror = str + " is invalid!"; }else if(nret == 1) { strerror = "find more than one face!"; }else if(nret == 2) { strerror = "quality check failed!"; } if(!strerror.isEmpty()) { QFile::remove(str); QMessageBox::critical(NULL,"critical", strerror, QMessageBox::Yes); return; } } //qDebug() << "---1-begin---update---index:" << index; QSqlQuery query; if(imageupdate) { query.prepare("update " + m_table + " set name = :name, feature_data=:feature_data, facex=:facex,facey=:facey,facewidth=:facewidth,faceheight=:faceheight where id=" + QString::number(index)); QByteArray bytearray; bytearray.resize(1024 * sizeof(float)); memcpy(bytearray.data(), features, 1024 * sizeof(float)); query.bindValue(":feature_data", QVariant(bytearray)); query.bindValue(":facex", rect.x); query.bindValue(":facey", rect.y); query.bindValue(":facewidth", rect.width); query.bindValue(":faceheight", rect.height); }else { query.prepare("update " + m_table + " set name = :name where id=" + QString::number(index)); } query.bindValue(":name", ui->db_editname->text());//fileinfo.fileName());//strfile); if(!query.exec()) { if(imageupdate) { QFile::remove(str); QFile::remove(m_image_tmp_path + gcrop_prefix + iter->second->image_path); } //QFile::remove() //qDebug() << "failed to update table:" << query.lastError(); QMessageBox::critical(NULL, "critical", tr("update data to database failed!"), QMessageBox::Yes); return; } //qDebug() << "---ddd-begin---update---index:" << index; iter->second->name = ui->db_editname->text(); if(imageupdate) { memcpy(iter->second->features, features, 1024 * sizeof(float)); //qDebug() << "---image-begin---update---index:" << index << ",image:" << str; QFile::remove(m_image_path + iter->second->image_path); QFile::remove(m_image_path + gcrop_prefix + iter->second->image_path); QFile::copy(str, m_image_path + iter->second->image_path); QFile::copy(m_image_tmp_path + gcrop_prefix + iter->second->image_path, m_image_path + gcrop_prefix + iter->second->image_path); QFile::remove(str); QFile::remove(m_image_tmp_path + gcrop_prefix + iter->second->image_path); } int row = ui->dbtableview->currentIndex().row(); //qDebug() << "showfaceinfo:" << row ; if(row >= 0) { QModelIndex index = m_model->index(row, 1); m_model->itemFromIndex(index)->setText(ui->db_editname->text()); //qDebug() << "---image-begin---update---index:" << index << ",image:" << str; if(imageupdate) { index = m_model->index(row, 2); ui->dbtableview->indexWidget(index)->setStyleSheet("border-image:url(" + m_image_path + iter->second->image_path + ")"); ui->db_editcrop->setStyleSheet("border-image:url(" + m_image_path + gcrop_prefix + iter->second->image_path + ")"); } } QMessageBox::information(NULL, "info", tr("update name to database success!"), QMessageBox::Yes); } void MainWindow::on_previewrunbtn_clicked() { m_videothread->m_exited = false; m_videothread->start(m_type); ui->previewrunbtn->setEnabled(false); ui->previewstopbtn->setEnabled(true); } void MainWindow::on_previewstopbtn_clicked() { m_videothread->m_exited = true; } void MainWindow::on_settingsavebtn_clicked() { /* ResetModelProcessDlg dialog(this, m_resetmodelthread); //m_resetmodelthread->start(&m_datalst, m_table, fr); int nret = dialog.exec(); qDebug() << "ResetModelProcessDlg:" << nret; if(nret != QDialog::Accepted) { QMessageBox::critical(NULL, "critical", "reset face recognizer model failed!", QMessageBox::Yes); return; } return; */ ////////////////////////////////// int size = ui->fdminfacesize->text().toInt(); if(size < 20 || size > 1000) { QMessageBox::warning(NULL, "warn", "Face Detector Min Face Size is invalid!", QMessageBox::Yes); return; } float value = ui->fdthreshold->text().toFloat(); if(value >= 1.0 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Face Detector Threshold is invalid!", QMessageBox::Yes); return; } value = ui->antispoofclarity->text().toFloat(); if(value >= 1.0 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Anti Spoofing Clarity is invalid!", QMessageBox::Yes); return; } value = ui->antispoofreality->text().toFloat(); if(value >= 1.0 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Anti Spoofing Reality is invalid!", QMessageBox::Yes); return; } value = ui->yawlowthreshold->text().toFloat(); if(value >= 90 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Quality Yaw Low Threshold is invalid!", QMessageBox::Yes); return; } value = ui->yawhighthreshold->text().toFloat(); if(value >= 90 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Quality Yaw High Threshold is invalid!", QMessageBox::Yes); return; } value = ui->pitchlowthreshold->text().toFloat(); if(value >= 90 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Quality Pitch Low Threshold is invalid!", QMessageBox::Yes); return; } value = ui->pitchhighthreshold->text().toFloat(); if(value >= 90 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Quality Pitch High Threshold is invalid!", QMessageBox::Yes); return; } value = ui->fr_threshold->text().toFloat(); if(value >= 1.0 || value < 0.0) { QMessageBox::warning(NULL, "warn", "Face Recognizer Threshold is invalid!", QMessageBox::Yes); return; } QString strmodel = ui->fr_modelpath->text().trimmed(); QFileInfo fileinfo(gmodelpath.c_str() + strmodel); if(QString::compare(fileinfo.suffix(), "csta", Qt::CaseInsensitive) != 0) { QMessageBox::warning(NULL, "warn", "Face Recognizer model file is invalid!", QMessageBox::Yes); return; } QMessageBox::StandardButton result; if(QString::compare(gparamters.Fr_ModelPath, ui->fr_modelpath->text().trimmed()) != 0) { result = QMessageBox::warning(NULL, "warning", "Set new face recognizer model need reset features, Are you sure?", QMessageBox::Yes | QMessageBox::No); if(result == QMessageBox::No) { return; } seeta::FaceRecognizer * fr = m_videothread->CreateFaceRecognizer(ui->fr_modelpath->text().trimmed()); ResetModelProcessDlg dialog(this, m_resetmodelthread); m_resetmodelthread->start(&m_datalst, m_table, fr); int nret = dialog.exec(); qDebug() << "ResetModelProcessDlg:" << nret; if(nret != QDialog::Accepted) { delete fr; QMessageBox::critical(NULL, "critical", "reset face recognizer model failed!", QMessageBox::Yes); return; } m_videothread->set_fr(fr); } QString sql("update " + m_config_table + " set fd_minfacesize=%1, fd_threshold=%2, antispoof_clarity=%3, antispoof_reality=%4,"); sql += "qa_yawlow=%5, qa_yawhigh=%6, qa_pitchlow=%7, qa_pitchhigh=%8, fr_threshold=%9,fr_modelpath=\"%10\""; sql = QString(sql).arg(ui->fdminfacesize->text()).arg(ui->fdthreshold->text()).arg(ui->antispoofclarity->text()).arg(ui->antispoofreality->text()). arg(ui->yawlowthreshold->text()).arg(ui->yawhighthreshold->text()).arg(ui->pitchlowthreshold->text()).arg(ui->pitchhighthreshold->text()). arg(ui->fr_threshold->text()).arg(ui->fr_modelpath->text().trimmed()); QSqlQuery q(sql); //qDebug() << sql; //QSqlQuery q("update " + m_config_table + " set min_face_size =" + ui->fdminfacesize->text() ); if(!q.exec()) { QMessageBox::critical(NULL, "critical", "update setting failed!", QMessageBox::Yes); return; } gparamters.MinFaceSize = ui->fdminfacesize->text().toInt(); gparamters.Fd_Threshold = ui->fdthreshold->text().toFloat(); gparamters.AntiSpoofClarity = ui->antispoofclarity->text().toFloat(); gparamters.AntiSpoofReality = ui->antispoofreality->text().toFloat(); gparamters.YawLowThreshold = ui->yawlowthreshold->text().toFloat(); gparamters.YawHighThreshold = ui->yawhighthreshold->text().toFloat(); gparamters.PitchLowThreshold = ui->pitchlowthreshold->text().toFloat(); gparamters.PitchHighThreshold = ui->pitchhighthreshold->text().toFloat(); gparamters.Fr_Threshold = ui->fr_threshold->text().toFloat(); gparamters.Fr_ModelPath = ui->fr_modelpath->text().trimmed(); m_videothread->setparamter(); QMessageBox::information(NULL, "info", "update setting ok!", QMessageBox::Yes); } void MainWindow::on_rotatebtn_clicked() { QMatrix matrix; matrix.rotate(90); int id = ui->db_editid->text().toInt(); std::map::iterator iter = m_datalst.find(id); if(iter == m_datalst.end()) { return; } //QFile::remove(m_image_tmp_path + iter->second->image_path); if(!QFile::exists(m_image_tmp_path + iter->second->image_path)) { QFile::copy(m_image_path + iter->second->image_path, m_image_tmp_path + iter->second->image_path); } if(!QFile::exists(m_image_tmp_path + gcrop_prefix + iter->second->image_path)) { QFile::copy(m_image_path + gcrop_prefix + iter->second->image_path, m_image_tmp_path + gcrop_prefix + iter->second->image_path); } //QFile::copy(m_image_path + iter->second->image_path, m_image_tmp_path + iter->second->image_path); QImage image(m_image_tmp_path + iter->second->image_path); if(image.isNull()) return; image = image.transformed(matrix, Qt::FastTransformation); image.save(m_image_tmp_path + iter->second->image_path); ui->db_editpicture->setStyleSheet("border-image:url(" + m_image_tmp_path + iter->second->image_path + ")"); /////////////////////// //QMatrix cropmatrix; matrix.reset(); matrix.rotate(90); QImage cropimage(m_image_tmp_path + gcrop_prefix + iter->second->image_path); if(cropimage.isNull()) return; cropimage = cropimage.transformed(matrix, Qt::FastTransformation); cropimage.save(m_image_tmp_path + gcrop_prefix + iter->second->image_path); ui->db_editcrop->setStyleSheet("border-image:url(" + m_image_tmp_path + gcrop_prefix + iter->second->image_path + ")"); } void MainWindow::on_tabWidget_currentChanged(int index) { //qDebug() << "cur:" << ui->tabWidget->tabText(index) << ",old:" << ui->tabWidget->tabText(m_currenttab) ; if(m_currenttab != index) { if(m_currenttab == 2) { on_previewstopbtn_clicked(); m_videothread->wait(); } m_currenttab = index; } //qDebug() << "tab:" << ui->tabWidget->tabText(index) << ",cur:" << index << ",old:" << ui->tabWidget->currentIndex(); } void MainWindow::on_addimagebtn_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("open image file"), "./" , "JPEG Files(*.jpg *.jpeg);;PNG Files(*.png);;BMP Files(*.bmp)"); //qDebug() << "image:" << fileName; QImage image(fileName); if(image.isNull()) return; QFile file(fileName); QFileInfo fileinfo(fileName); ////////////////////////////// QSqlQuery query; query.prepare("insert into " + m_table + " (id, name, image_path, feature_data, facex,facey,facewidth,faceheight) values (:id, :name, :image_path, :feature_data,:facex,:facey,:facewidth,:faceheight)"); int index = 1; if(m_model->rowCount() > 0) { index = m_model->item(m_model->rowCount() - 1, 0)->text().toInt() + 1; } QString strfile = QString::number(index) + "_" + fileinfo.fileName();//m_image_path + QString::number(index) + "_" + m_currentimagefile;//fileinfo.fileName(); QString cropfile = m_image_path + gcrop_prefix + strfile; float features[1024]; SeetaRect rect; int nret = m_videothread->checkimage(fileName, cropfile, features, rect); QString strerror; if(nret == -2) { strerror = "do not find face!"; }else if(nret == -1) { strerror = fileName + " is invalid!"; }else if(nret == 1) { strerror = "find more than one face!"; }else if(nret == 2) { strerror = "quality check failed!"; } if(!strerror.isEmpty()) { QMessageBox::critical(NULL,"critical", strerror, QMessageBox::Yes); return; } QString name = fileinfo.completeBaseName();//fileName(); int n = name.indexOf("_"); if(n >= 1) { name = name.left(n); } query.bindValue(0, index); query.bindValue(1,name); //query.bindValue(2, "/wqy/Downloads/ap.jpeg"); query.bindValue(2, strfile);//fileinfo.fileName());//strfile); //float data[4] = {0.56,0.223,0.5671,-0.785}; QByteArray bytearray; bytearray.resize(1024 * sizeof(float)); memcpy(bytearray.data(), features, 1024 * sizeof(float)); query.bindValue(3, QVariant(bytearray)); query.bindValue(4, rect.x); query.bindValue(5, rect.y); query.bindValue(6, rect.width); query.bindValue(7, rect.height); if(!query.exec()) { QFile::remove(cropfile); qDebug() << "failed to insert table:" << query.lastError(); QMessageBox::critical(NULL, "critical", tr("save face data to database failed!"), QMessageBox::Yes); return; } file.copy(m_image_path + strfile); DataInfo * info = new DataInfo(); info->id = index; info->name = name; info->image_path = strfile; memcpy(info->features, features, 1024 * sizeof(float)); info->x = rect.x; info->y = rect.y; info->width = rect.width; info->height = rect.height; m_datalst.insert(std::map::value_type(index, info)); //////////////////////////////////////////////////////////// int rows = m_model->rowCount(); //qDebug() << "rows:" << rows; m_model->setItem(rows, 0, new QStandardItem(QString::number(index))); m_model->setItem(rows, 1, new QStandardItem(info->name)); QLabel *label = new QLabel(""); label->setStyleSheet("border-image:url(" + m_image_path + strfile + ")"); ui->dbtableview->setIndexWidget(m_model->index(rows, 2), label); QPushButton *button2 = new QPushButton("delete"); button2->setProperty("id", index); button2->setFixedSize(80, 40); connect(button2, SIGNAL(clicked()), this, SLOT(deleterecord())); QWidget *widget = new QWidget(); QHBoxLayout *layout = new QHBoxLayout; layout->addStretch(); layout->addWidget(button2); layout->addStretch(); widget->setLayout(layout); ui->dbtableview->setIndexWidget(m_model->index(rows, 3), widget); ui->dbtableview->scrollToBottom(); ui->dbtableview->selectRow(rows); emit ui->dbtableview->clicked(m_model->index(rows, 1)); //QMessageBox::information(NULL, "info", tr("add face operator success!"), QMessageBox::Yes); } void MainWindow::on_menufacedbbtn_clicked() { ui->tabWidget->setCurrentIndex(1); } void MainWindow::on_menusettingbtn_clicked() { ui->tabWidget->setCurrentIndex(3); } void MainWindow::on_previewclearbtn_clicked() { ui->previewtableview->setUpdatesEnabled(false); m_videomodel->removeRows(0, m_videomodel->rowCount()); //m_videomodel->clear(); ui->previewtableview->setUpdatesEnabled(true); } void MainWindow::on_menuopenvideofile_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("open video file"), "./" , "MP4 Files(*.mp4 *.MP4);;AVI Files(*.avi);;FLV Files(*.flv);;h265 Files(*.h265);;h263 Files(*.h263)"); //qDebug() << "image:" << fileName; m_type.type = 1; m_type.filename = fileName; m_type.title = "Open Video: " + fileName; ui->recognize_label->setText(m_type.title); ui->tabWidget->setCurrentIndex(2); emit ui->previewrunbtn->clicked(); } void MainWindow::on_menuopenpicturefile_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("open image file"), "./" , "JPEG Files(*.jpg *.jpeg);;PNG Files(*.png);;BMP Files(*.bmp)"); //qDebug() << "image:" << fileName; m_type.type = 2; m_type.filename = fileName; m_type.title = "Open Image: " + fileName; ui->recognize_label->setText(m_type.title); ui->tabWidget->setCurrentIndex(2); emit ui->previewrunbtn->clicked(); } void MainWindow::on_menuopencamera_clicked() { m_type.type = 0; m_type.filename = ""; m_type.title = "Open Camera: 0"; ui->recognize_label->setText(m_type.title); ui->tabWidget->setCurrentIndex(2); emit ui->previewrunbtn->clicked(); } static void FindFile(const QString & path, QStringList &files) { QDir dir(path); if(!dir.exists()) return; dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); dir.setSorting(QDir::DirsFirst);; QFileInfoList list = dir.entryInfoList(); int i = 0; while(i < list.size()) { QFileInfo info = list.at(i); //qDebug() << info.absoluteFilePath(); if(info.isDir()) { FindFile(info.absoluteFilePath(), files); }else { QString str = info.suffix(); if(str.compare("png", Qt::CaseInsensitive) == 0 || str.compare("jpg", Qt::CaseInsensitive) == 0 || str.compare("jpeg", Qt::CaseSensitive) == 0 || str.compare("bmp", Qt::CaseInsensitive) == 0) { files.append(info.absoluteFilePath()); } } i++; } return; } void MainWindow::on_addfilesbtn_clicked() { QString fileName = QFileDialog::getExistingDirectory(this, tr("Select Directorky"), "."); if(fileName.isEmpty()) { return; } qDebug() << fileName; QStringList files; FindFile(fileName, files); qDebug() << files.size(); if(files.size() <= 0) return; for(int i=0; irowCount() > 0) { index = m_model->item(m_model->rowCount() - 1, 0)->text().toInt(); } InputFilesProcessDlg dialog(this, m_inputfilesthread); m_inputfilesthread->start(&files, index, m_table); dialog.exec(); //qDebug() << "------on_addfilesbtn_clicked---end"; } void MainWindow::oninputfilesupdateui(std::vector * datas) { DataInfo * info = NULL; //qDebug() << "----oninputfilesupdateui--" << datas->size(); if(datas->size() > 0) { ui->dbtableview->setUpdatesEnabled(false); } int rows = 0; for(int i=0; isize(); i++) { rows = m_model->rowCount(); //qDebug() << "rows:" << rows; info = (*datas)[i]; m_datalst.insert(std::map::value_type(info->id, info)); m_model->setItem(rows, 0, new QStandardItem(QString::number(info->id))); m_model->setItem(rows, 1, new QStandardItem(info->name)); QLabel *label = new QLabel(""); label->setStyleSheet("border-image:url(" + m_image_path + info->image_path + ")"); ui->dbtableview->setIndexWidget(m_model->index(rows, 2), label); QPushButton *button2 = new QPushButton("delete"); button2->setProperty("id", info->id); button2->setFixedSize(80, 40); connect(button2, SIGNAL(clicked()), this, SLOT(deleterecord())); ui->dbtableview->setIndexWidget(m_model->index(rows, 3), button2); //ui->dbtableview->scrollToBottom(); //ui->dbtableview->selectRow(rows); } if(datas->size() > 0) { ui->dbtableview->setUpdatesEnabled(true); ui->dbtableview->scrollToBottom(); ui->dbtableview->selectRow(rows); emit ui->dbtableview->clicked(m_model->index(rows, 1)); } } void MainWindow::on_settingselectmodelbtn_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("open model file"), "./" , "CSTA Files(*.csta)"); QFileInfo fileinfo(fileName); QString modelfile = fileinfo.fileName(); QString str = gmodelpath.c_str() + modelfile; qDebug() << "------str:" << str; qDebug() << "fileName:" << fileName; if(QString::compare(fileName, str) == 0) { ui->fr_modelpath->setText(modelfile); return; } //QFile file(fileName); if(!QFile::copy(fileName, str)) { QMessageBox::critical(NULL, "critical", "Copy model file: " + fileName + " to " + gmodelpath.c_str() + " failed, file already exists!", QMessageBox::Yes); return; } ui->fr_modelpath->setText(modelfile); //m_videothread->reset_fr_model(modelfile); //qDebug() << "image:" << fileName; } void MainWindow::closeEvent(QCloseEvent *event) { m_videothread->m_exited = true; m_videothread->wait(); QWidget::closeEvent(event); }