//#pragma execution_character_set("gbk") #include "widget.h" #include #include #include #include "ui_widget.h" #include #include "datavar.h" #include "mainshowwidget.h" #include "loginwindow.h" #include "opencv2/opencv.hpp" #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include #include #include "globaldef.h" #include #include "base64.h" #include "client.h" #include "util.h" #include "readonlydelegate.h" #include "PreprocessWindow.h" #include "container/threadsafequeue.h" #include "ImgProcessAlg.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)/*, DataVar::g_picRefWarp(), DataVar::g_picDet()*/,m_homMat2d() { qRegisterMetaType("QString"); ui->setupUi(this); m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(realTimeShowImage())); m_timer->start(50); m_picShow = QSharedPointer(new QImage); ui->LABEL_mainTitle->setText(ST_SOFTWARE_NAME + " " + ST_SOFTWARE_VERSION); /*****************信号槽连接*****************/ connect(PostClient::getInstance(), SIGNAL(sendInformation(QString,int)), this, SLOT(informationDisplay(QString, int)));//服务器通信结果->信息显示框 connect(PostClient::getInstance(), SIGNAL(sendParseResult(std::multimap)), this, SLOT(receiveParseResult(std::multimap)));//服务器通信极耳解析信息->接收,画框,显示 connect(this, SIGNAL(sig_infoDisplay(QString)), this, SLOT(informationDisplay(QString)));//服务器通信结果->信息显示框 //connect(ui->CBK_IsShowRltRect, SIGNAL(stateChanged(int)), this, SLOT(on_CBK_RltRectShow_StateChanged(int))); connect(ui->label_source, SIGNAL(showEnlarge()), this, SLOT(enlargeImg()),Qt::QueuedConnection);//放大test_label ROI内图像 connect(ui->label_source, SIGNAL(sig_mouseLeave()), this, SLOT(clearImg()), Qt::QueuedConnection);//放大test_label ROI内图像 connect(ui->label_source, SIGNAL(sig_mouseRightPress()), this, SLOT(slot_changeShowMode())); connect(ui->CBK_IsShowRltRect, SIGNAL(stateChanged(int)), this, SLOT(createDealedImage(int))); connect(ui->CBK_IsShowRltText, SIGNAL(stateChanged(int)), this, SLOT(createDealedImage(int))); connect(ui->label_source, SIGNAL(sig_RectAlgChangedRef(QRect)), this, SLOT(on_RectAlgChangedRef(QRect)));//获取最新的参考图ROI //connect(this, SIGNAL(sig_updataCamInfo(CamParInfo)), m_camParam, SLOT(updataCamInfoToForm(CamParInfo)));//获取最新的参考图ROI connect(DataVar::instance()->g_thWork.data(), SIGNAL(sig_runAlg()), this, SLOT(matchAndRunAlg())); connect(this, SIGNAL(sig_algReady()), DataVar::instance()->g_thWork.data(), SLOT(changeAlgState())); connect(ui->TWG_resulrInfo, SIGNAL(cellClicked(int, int)), this, SLOT(slot_TWG_resulrInfo_Clicked(int, int))); connect(ui->TWG_resulrInfo, SIGNAL(itemSelectionChanged()), this, SLOT(slot_TWG_resulrInfo_SelectChanged())); connect(&m_watcher, &FileWatcher::sig_dirStateChange, this, [=](const QString& path) { informationDisplay("directoryChanged path = " + path); }); login();//用户登录 on_RBT_FileMode_clicked(true);//设置刚启动默认为本地模式 ui->BTN_ConfigCamera->setStyleSheet(ST_MAIN_BUTTON_QSS(":/Assets/View/set.png")); ui->BTN_OpenImageRef->setStyleSheet(ST_MAIN_BUTTON_QSS(":/Assets/View/Open.png")); ui->BTN_OpenImageDet->setStyleSheet(ST_MAIN_BUTTON_QSS(":/Assets/View/Open.png")); ui->BTN_TakePhotoRef->setStyleSheet(ST_MAIN_BUTTON_QSS(":/Assets/View/cam.png")); ui->BTN_AlgDetect->setStyleSheet(ST_MAIN_BUTTON_QSS(":/Assets/View/run.png")); ui->BTN_SaveImage->setStyleSheet(ST_MAIN_BUTTON_QSS(":/Assets/View/Save_as.png")); //ui->BTN_ConfigCamera->setSizePolicy(QSizePolicy::Policy::MinimumExpanding, QSizePolicy::Policy::Preferred); ui->EDIT_informationText->document()->setMaximumBlockCount(15); setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); setWindowState(Qt::WindowState::WindowMaximized); changeCamOrFileMode(); DataVar::g_frmCamParam = new CameraPar(); //相机参数配置窗口 // //设置表格列宽 // ui->TWG_resulrInfo->setColumnWidth(2, 50); // ////设置表格行间距 ////ui->TWG_resulrInfo->verticalHeader()->setDefaultSectionSize(15); ////ui->TWG_resulrInfo->verticalHeader()->setMinimumSectionSize(15); // //隐藏水平header // ui->TWG_resulrInfo->verticalHeader()->setVisible(false); // ui->TWG_resulrInfo->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行 // ui->TWG_resulrInfo->setSelectionMode(QAbstractItemView::SingleSelection); //设置只能单选 // //connect(ui.tableWidget, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(slot_DoubleClicked(int, int))); // ReadOnlyDelegate* readOnlyDelegate = new ReadOnlyDelegate(this); // ui->TWG_resulrInfo->setItemDelegateForColumn(0, readOnlyDelegate); //设置第1列只读 // int count = ui->TWG_resulrInfo->rowCount(); // ui->TWG_resulrInfo->setRowCount(20); //设置行数 // QTableWidgetItem* item_name = new QTableWidgetItem("55555588888888888888885555555555555555"); // //item_name->setFlags(item_name->flags() & (~Qt::ItemIsEditable)); //设置列不可编辑 // item_name->setTextAlignment(Qt::AlignLeft); // //item_name->setTextAlignment(Qt::AlignVCenter); // ui->TWG_resulrInfo->setItem(0, 0, item_name); // ui->TWG_resulrInfo->setItem(1, 0, new QTableWidgetItem("2222")); ui->TWG_resulrInfo->setStyleSheet(ST_QTABLEWIDGET_QSS); ui->TWG_resulrInfo->horizontalHeader()->setStyleSheet(ST_QTABLEWIDGET_HEADER_QSS); // 列数 ui->TWG_resulrInfo->setColumnCount(2); //ui->TWG_resulrInfo->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Stretch); ui->TWG_resulrInfo->setColumnWidth(0, 100); ui->TWG_resulrInfo->horizontalHeader()->setStretchLastSection(true);//最后一列填充空白部分 // 设置文字左对齐 ui->TWG_resulrInfo->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); // 设置表头文字 QStringList headers; headers << ("Index") << ("Errors"); ui->TWG_resulrInfo->setHorizontalHeaderLabels(headers); // 设置为不可编辑 ui->TWG_resulrInfo->setEditTriggers(QAbstractItemView::NoEditTriggers); // 设置为整行选中模式 ui->TWG_resulrInfo->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行 ui->TWG_resulrInfo->setSelectionMode(QAbstractItemView::SingleSelection); //设置只能单选 // 设置最左侧的序号不用显示 ui->TWG_resulrInfo->verticalHeader()->setVisible(false); ////设置表格行间距 //ui->TWG_resulrInfo->verticalHeader()->setDefaultSectionSize(15); //ui->TWG_resulrInfo->verticalHeader()->setMinimumSectionSize(15); //隐藏水平header ui->BTN_AlgDetect->setShortcut(Qt::Key_Space); } /*****************用户登录*****************/ void Widget::login() { LoginUIWindow* loginWindow = new LoginUIWindow(); loginWindow->show();//显示登录页面 connect(loginWindow, SIGNAL(loginMainWindow()), this, SLOT(show())); } /*****************文本框消息提示*****************/ void Widget::informationDisplay(QString str, int logType) { QDateTime dateTime = QDateTime::currentDateTime(); QString date = dateTime.toString("yyyy-MM-dd hh:mm:ss");//添加时间戳 ui->EDIT_informationText->append(date + ": \n" + str); switch (logType) { case 0: { LOG_DEBUG(str.toLocal8Bit().toStdString().c_str()); } break; case 1: { LOG_INFO(str.toLocal8Bit().toStdString().c_str()); } break; case 2: { LOG_WARN(str.toLocal8Bit().toStdString().c_str()); } break; case 3: { LOG_ERROR(str.toLocal8Bit().toStdString().c_str()); } break; default: break; } QApplication::processEvents();//立即刷新文本框 } void Widget::slot_changeShowMode() { if (DataVar::g_winShowMode & 4) DataVar::g_winShowMode &= 3; else DataVar::g_winShowMode |= 4; enlargeImg(); update(); } /*****************向服务器发送图片base64*****************/ void Widget::PostImg() { emit sig_infoDisplay(QStringLiteral("上传图片...")); std::string img_data1 = base64_encode(DataVar::instance()->getPicRefRaw().data(), DataVar::instance()->getPicRefRaw().size(), false); std::string img_data2 = base64_encode(DataVar::instance()->getPicDetRaw().data(), DataVar::instance()->getPicDetRaw().size(), false); PostClient::getInstance()->PostImgToServer(img_data2,img_data1);//调用PostImgToServer发送请求 emit sig_infoDisplay(QStringLiteral("检测中...")); } /*****************接收服务器返回参数*****************/ void Widget::receiveParseResult(std::multimap errorsRect) { if (!errorsRect.empty()) { ui->TWG_resulrInfo->setRowCount(errorsRect.size()); int id = 0; QTableWidgetItem* first_item_value = nullptr; for (auto iter = errorsRect.begin(); iter != errorsRect.end(); iter++) { iter->second.translate(m_roiAlgDet.x(), m_roiAlgDet.y()); //ui->TWG_resulrInfo->insertRow(ui->TWG_resulrInfo->rowCount());//增加一行 QTableWidgetItem* item_name = new QTableWidgetItem(QString::number(iter->first)); item_name->setFlags(item_name->flags() & (~Qt::ItemIsEditable)); //设置列不可编辑 item_name->setTextAlignment(Qt::AlignLeft); item_name->setTextAlignment(Qt::AlignVCenter); ui->TWG_resulrInfo->setItem(id, 0, item_name); QTableWidgetItem* item_value = new QTableWidgetItem(QString::number(iter->second.topLeft().x()) + "," + QString::number(iter->second.topLeft().y()) + "," + QString::number(iter->second.width()) + "," + QString::number(iter->second.height())); item_name->setFlags(item_name->flags() & (~Qt::ItemIsEditable)); //设置列不可编辑 item_name->setTextAlignment(Qt::AlignLeft); item_name->setTextAlignment(Qt::AlignVCenter); ui->TWG_resulrInfo->setItem(id, 1, item_value); if (id == 0) first_item_value = item_value; id++; } ui->TWG_resulrInfo->setFocus(); //获取焦点 if (first_item_value) ui->TWG_resulrInfo->setCurrentItem(first_item_value);//默认第一个为选中 DataVar::instance()->setErrorRects(errorsRect); createDealedImage(); saveRltImage(); } ui->BTN_AlgDetect->setEnabled(true); if (DataVar::g_camOrFileMode == 0) { emit sig_algReady(); } } void Widget::createDealedImage(int){ int flag = (0 |(ui->CBK_IsShowRltText->isChecked() ? 4 :0)) | (ui->CBK_IsShowRltRect->isChecked() ? 2 : 0); DataVar::instance()->createDealedImage(flag); if (flag>0) m_picShow = DataVar::instance()->getPicDealed(); else m_picShow = DataVar::instance()->getPicDet(); if (DataVar::g_winShowMode & 2) showqImageSource(*m_picShow, 2); } /*****************enlarge框放大图片*****************/ void Widget::enlargeImg() { QRect roi = ui->label_source->getRoiRect();//获取绿框所在区域ROI int x = roi.x(); int y = roi.y(); int w = roi.width(); int h = roi.height(); if (DataVar::g_winShowMode & 2) { QPixmap enlargeDetImg; QPixmap enlargeSourceImg = QPixmap::fromImage(DataVar::instance()->getPicRefWarp()->copy(x, y, w, h)); if (DataVar::g_winShowMode & 4) enlargeDetImg = QPixmap::fromImage(DataVar::instance()->getPicDet()->copy(x, y, w, h)); else enlargeDetImg = QPixmap::fromImage(m_picShow->copy(x, y, w, h)); //QPixmap enlargeDetImg = QPixmap::fromImage(DataVar::instance()->getPicDet()->copy(x, y, w, h)); int with = ui->label_ori->width(); int height = ui->label_ori->height(); enlargeSourceImg = enlargeSourceImg.scaled(with, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); // 按比例缩放 enlargeDetImg = enlargeDetImg.scaled(with, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); // 按比例缩放 ui->label_ori->setPixmap(enlargeSourceImg); ui->label_ori->show(); ui->label_rlt->setPixmap(enlargeDetImg); ui->label_rlt->show(); } else { if (!m_picShow->isNull()) { QPixmap enlargeSourceImg = QPixmap::fromImage(m_picShow->copy(x, y, w, h)); int with = ui->label_ori->width(); int height = ui->label_ori->height(); enlargeSourceImg = enlargeSourceImg.scaled(with, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); // 按比例缩放 ui->label_ori->setPixmap(enlargeSourceImg); ui->label_ori->show(); ui->label_rlt->clear(); } } } void Widget::clearImg() { ui->label_ori->clear(); ui->label_rlt->clear(); } void Widget::showqImage(QImage image, QLabel* gui) { int width = gui->width(); int height = gui->height(); QPixmap diaplayScaledpixmap = QPixmap::fromImage(image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation)); // 按比例缩放 gui->setPixmap(diaplayScaledpixmap); } void Widget::showqImageSource(QImage image,int refOrDetMode) { bool showMask = false; QRect q = QRect(); if (refOrDetMode ==0) { DataVar::g_winShowMode &= 4; ui->LABLE_ShowPicNmae->setText(""); } else if (refOrDetMode == 1) { DataVar::g_winShowMode &= 4; ui->LABLE_ShowPicNmae->setText(QStringLiteral("参考图")); q = m_roiAlgRef; } else { DataVar::g_winShowMode |= 2; showMask = true; q = m_roiAlgDet; ui->LABLE_ShowPicNmae->setText(QStringLiteral("检测图")); } ui->label_source->setBackImage(QPixmap::fromImage(image), showMask);//设置背景图 ui->label_source->setRectAlg(q); } void Widget::movepointSlot(QPointF point) { } Widget::~Widget() { if (m_timer->isActive()) m_timer->stop(); delete ui; } void Widget::on_RBT_CameraMode_clicked(bool checked) { if (checked) { ui->BTN_TakePhotoRef->setEnabled(true); //ui->BTN_TakePhotoDet->setStyle(true); ui->BTN_OpenImageRef->setEnabled(false); ui->BTN_OpenImageDet->setEnabled(false); changeCamOrFileMode(); } } void Widget::on_RBT_FileMode_clicked(bool checked) { if (checked) { ui->BTN_TakePhotoRef->setEnabled(false); //ui->BTN_TakePhotoDet->setStyle(false); ui->BTN_OpenImageRef->setEnabled(true); ui->BTN_OpenImageDet->setEnabled(true); changeCamOrFileMode(); } } /*****************检测图和模板图进行配准*****************/ void Widget::bfMatch(const cv::Mat& imageRef, const cv::Mat& imageDet, cv::Mat& imageOut) { using namespace cv; cv::Mat tr = imageRef; cv::Mat td = imageDet; //cv::resize(tr, tr, cv::Size(), 0.05, 0.05); //cv::resize(td, td, cv::Size(), 0.05, 0.05); //// Convert images to gray scale; //Mat im1_gray, im2_gray; //cvtColor(tr, im1_gray, cv::COLOR_BGR2GRAY); //cvtColor(td, im2_gray, cv::COLOR_BGR2GRAY); //// Define the motion model //const int warp_mode = MOTION_HOMOGRAPHY; //// Set a 2x3 or 3x3 warp matrix depending on the motion model. //Mat warp_matrix; //// Initialize the matrix to identity //if (warp_mode == MOTION_HOMOGRAPHY) // warp_matrix = Mat::eye(3, 3, CV_32F); //else // warp_matrix = Mat::eye(2, 3, CV_32F); //// Specify the number of iterations. //int number_of_iterations = 2000; //// Specify the threshold of the increment //// in the correlation coefficient between two iterations //double termination_eps = 1e-10; //// Define termination criteria //TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, number_of_iterations, termination_eps); //// Run the ECC algorithm. The results are stored in warp_matrix. //findTransformECC( // im1_gray, // im2_gray, // warp_matrix, // warp_mode, // criteria //); //std::vector ptso = { cv::Point2f(0,0), cv::Point2f(imageRef.size().width,0), cv::Point2f(imageRef.size().width,imageRef.size().height), cv::Point2f(0,imageRef.size().height) }; //std::vector ptsoo = { cv::Point2f(0,0), cv::Point2f(im1_gray.size().width,0), cv::Point2f(im1_gray.size().width,im1_gray.size().height), cv::Point2f(0,im1_gray.size().height) }; //std::vector ptsd,ptsdd; //ptsd.resize(4); //ptsdd.resize(4); //cv::perspectiveTransform(ptsoo, ptsdd, warp_matrix); //for (size_t i = 0; i < 4; i++) //{ // ptsd[i] = 20 * ptsdd[i]; //} //m_homMat2d = cv::getPerspectiveTransform(ptso, ptsd); //warpPerspective(imageRef, imageOut, m_homMat2d, imageDet.size(), INTER_LINEAR /*+ WARP_INVERSE_MAP*/); FeatureMatching featureExtractor; featureExtractor.ExtractDescriptors(td, 0); featureExtractor.ExtractDescriptors(tr, 1); featureExtractor.Matching(m_homMat2d,30); warpPerspective(tr, imageOut, m_homMat2d, td.size()); } void Widget::calRoiAlgDetFromRef() { if (!m_homMat2d.empty() && !DataVar::instance()->getPicDet()->isNull() && m_roiAlgRef != QRect(0, 0, 0, 0)) { QPolygon ply; QPoint p; FeatureMatching::AffinePoint(m_homMat2d, m_roiAlgRef.topLeft(), p); ply.append(p); FeatureMatching::AffinePoint(m_homMat2d, m_roiAlgRef.topRight(), p); ply.append(p); FeatureMatching::AffinePoint(m_homMat2d, m_roiAlgRef.bottomRight(), p); ply.append(p); FeatureMatching::AffinePoint(m_homMat2d, m_roiAlgRef.bottomLeft(), p); ply.append(p); QRect boundingRect = DataVar::instance()->getPicDet()->rect(); boundingRect = boundingRect.intersected(ply.boundingRect()); m_roiAlgDet = boundingRect; } } void Widget::calstdev(float* A, int num,float& mean, float& stdev) { float sum = std::accumulate(A, A + num-1, 0.0); mean = sum / num; //均值 float accum = 0.0; for (size_t i = 0; i < num; i++) { accum += pow((A[i] - mean),2); } stdev = sqrt(accum /num); //标准差 } void Widget::closeEvent(QCloseEvent* event) { QWidget::closeEvent(event); } void Widget::wheelEvent(QWheelEvent* event) { QWidget::wheelEvent(event); } void Widget::initRoiAlgRef(QSharedPointer pix) { float rectExpandWidthFactor = 0.05; int sampleStep = 40; //采样步长(模糊系数) int gradientThresh = 50; //梯度阈值 #if 1 int idxL, idxR, idyT, idyB = -1; calRoiInfo(qImage_to_cvMat(*pix), idxL, idxR, idyT, idyB, rectExpandWidthFactor, sampleStep, gradientThresh); if (idxL < idxR && idyT < idyB) { int ww = idxR - idxL; int hh = idyB - idyT; int expandValueW = ww * rectExpandWidthFactor; int expandValueH = hh * rectExpandWidthFactor; m_roiAlgRef = QRect(idxL - expandValueW, idyT - expandValueH, ww + 2* expandValueW, hh + 2* expandValueH).intersected(QRect(0, 0, m_picShow->width(), m_picShow->height())); } else m_roiAlgRef = QRect(0, 0, m_picShow->width(), m_picShow->height()); //cv::normalize(imgToProj, imgToProj, 0, 255, cv::NORM_MINMAX); //cv::medianBlur(imgToProj, imgToProj, 11); //double minValue, maxValue; // 最大值,最小值 //cv::Point minIdx, maxIdx; // 最小值坐标,最大值坐标 //cv::minMaxLoc(imgToProj, &minValue, &maxValue, &minIdx, &maxIdx); //double f = 255 / (maxValue - minValue); //double add = -f * minValue; //imgToProj.convertTo(imgToProj, CV_8UC1, f, add); //cv::normalize(imgToProj, imgToProj, f, add, cv::NORM_MINMAX); #else m_roiAlgRef = QRect(0, 0, m_picShow->width(), m_picShow->height()); #endif // 0 } void Widget::setRefPic(const QImage& pix, const std::vector& picRaw) { if (!pix.isNull()) { DataVar::instance()->setPicRef(QSharedPointer(new QImage(pix))); DataVar::instance()->setPicRefWarp(DataVar::instance()->getPicRef()); DataVar::instance()->setPicRefRaw(picRaw); m_picShow = DataVar::instance()->getPicRefWarp(); emit sig_infoDisplay(QStringLiteral("参考图设置成功!")); //同步显示缩略图 ui->LABLE_ShowSmallPicRef->setPixmap(QPixmap::fromImage(DataVar::instance()->getPicRef()->scaled(ui->LABLE_ShowSmallPicRef->width(), ui->LABLE_ShowSmallPicRef->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); ui->LABLE_ShowSmallPicRef->setTextOnPos("Ref", 15, 15); ui->LABLE_ShowSmallPicRef->show(); initRoiAlgRef(DataVar::instance()->getPicRef()); showqImageSource(*m_picShow, 1); } else { QMESSAGEBOX_ERROR(CN("设置参考图失败!")); } } void Widget::setDetPic(const cv::Mat& img) { if (DataVar::instance()->getPicRef()->isNull()) { QMESSAGEBOX_WARN(CN("请先设定参考图!")); return; } if (!img.empty()) { DataVar::instance()->setPicDet(MatToQImage(img)); DataVar::instance()->setPicDealed(DataVar::instance()->getPicDet()); setDetPicInner(img); } else { QMESSAGEBOX_ERROR(CN("设置检测图失败!")); } } void Widget::setRefPic(const cv::Mat& img) { if (!img.empty()) { DataVar::instance()->setPicRef(MatToQImage(img)); DataVar::instance()->setPicRefWarp(DataVar::instance()->getPicRef()); m_picShow = DataVar::instance()->getPicRefWarp(); emit sig_infoDisplay(QStringLiteral("参考图设置成功!")); //同步显示缩略图 ui->LABLE_ShowSmallPicRef->setPixmap(QPixmap::fromImage(DataVar::instance()->getPicRef()->scaled(ui->LABLE_ShowSmallPicRef->width(), ui->LABLE_ShowSmallPicRef->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); ui->LABLE_ShowSmallPicRef->setTextOnPos("Ref", 15, 15); ui->LABLE_ShowSmallPicRef->show(); initRoiAlgRef(DataVar::instance()->getPicRef()); std::vector picRaw; cv::imencode(".jpg", img(cv::Rect(m_roiAlgRef.x(), m_roiAlgRef.y(), m_roiAlgRef.width(), m_roiAlgRef.height())), picRaw); DataVar::instance()->setPicRefRaw(picRaw); showqImageSource(*m_picShow, 1); } else { QMESSAGEBOX_ERROR(CN("设置参考图失败!")); } } void Widget::setDetPic(const cv::Mat& pix, const std::vector& picRaw) { if (DataVar::instance()->getPicRef()->isNull()) { QMESSAGEBOX_WARN(CN("请先设定参考图!")); return; } if (!pix.empty()) { DataVar::instance()->setPicDet(MatToQImage(pix)); DataVar::instance()->setPicDetRaw(picRaw); DataVar::instance()->setPicDealed(DataVar::instance()->getPicDet()); setDetPicInner(); } else { QMESSAGEBOX_ERROR(CN("设置检测图失败!")); } } void Widget::setDetPicInner() { m_picShow = DataVar::instance()->getPicDet(); emit sig_infoDisplay(QStringLiteral("对齐中...")); cv::Mat m; cv::Mat tmpPicRef = qImage_to_cvMat(*DataVar::instance()->getPicRef()); cv::Mat tmpPicDet = qImage_to_cvMat(*DataVar::instance()->getPicDet()); bfMatch(tmpPicRef, tmpPicDet, m); DataVar::instance()->setPicRefWarp(MatToQImage(m)); calRoiAlgDetFromRef(); //同步显示缩略图 ui->LABLE_ShowSmallPicDet->setPixmap(QPixmap::fromImage(DataVar::instance()->getPicDet()->scaled(ui->LABLE_ShowSmallPicDet->width(), ui->LABLE_ShowSmallPicDet->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); ui->LABLE_ShowSmallPicDet->setTextOnPos("Det", 15, 15); ui->LABLE_ShowSmallPicDet->show(); showqImageSource(*m_picShow, 2); emit sig_infoDisplay(QStringLiteral("检测图设置成功!")); } void Widget::setDetPicInner(const cv::Mat& img) { m_picShow = DataVar::instance()->getPicDet(); emit sig_infoDisplay(QStringLiteral("对齐中...")); cv::Mat m; cv::Mat tmpPicRef = qImage_to_cvMat(*DataVar::instance()->getPicRef()); cv::Mat tmpPicDet = qImage_to_cvMat(*DataVar::instance()->getPicDet()); bfMatch(tmpPicRef, tmpPicDet, m); DataVar::instance()->setPicRefWarp(MatToQImage(m)); calRoiAlgDetFromRef(); std::vector picRaw; cv::imencode(".jpg", img(cv::Rect(m_roiAlgDet.x(), m_roiAlgDet.y(), m_roiAlgDet.width(), m_roiAlgDet.height())), picRaw); DataVar::instance()->setPicDetRaw(picRaw); //同步显示缩略图 ui->LABLE_ShowSmallPicDet->setPixmap(QPixmap::fromImage(DataVar::instance()->getPicDet()->scaled(ui->LABLE_ShowSmallPicDet->width(), ui->LABLE_ShowSmallPicDet->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); ui->LABLE_ShowSmallPicDet->setTextOnPos("Det", 15, 15); ui->LABLE_ShowSmallPicDet->show(); showqImageSource(*m_picShow, 2); emit sig_infoDisplay(QStringLiteral("检测图设置成功!")); } void Widget::ExportExcel() { } void Widget::on_LABLE_ShowSmallPicDet_clicked() { if (ui->CBK_IsShowRltRect->isChecked() ) m_picShow = DataVar::instance()->getPicDealed(); else m_picShow = DataVar::instance()->getPicDet(); showqImageSource(*m_picShow,2); } void Widget::on_LABLE_ShowSmallPicRef_clicked() { m_picShow = DataVar::instance()->getPicRef(); showqImageSource(*m_picShow,1); } void Widget::resizeEvent(QResizeEvent *event) { //同步显示缩略图 if (!DataVar::instance()->getPicRef()->isNull()) ui->LABLE_ShowSmallPicRef->setPixmap(QPixmap::fromImage(DataVar::instance()->getPicRef()->scaled(ui->LABLE_ShowSmallPicRef->width(), ui->LABLE_ShowSmallPicRef->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); if (!DataVar::instance()->getPicDet()->isNull()) ui->LABLE_ShowSmallPicDet->setPixmap(QPixmap::fromImage(DataVar::instance()->getPicDet()->scaled(ui->LABLE_ShowSmallPicDet->width(), ui->LABLE_ShowSmallPicDet->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); enlargeImg(); } void Widget::on_BTN_OpenImageRef_clicked() { static QString staticDir = " "; clearRltInfo(); QString path = QFileDialog::getOpenFileName(this, QStringLiteral("打开图片(尚不支持中文路径)"), staticDir, "Image Files(*.jpg *.bmp);;All(*.*)"/*"Image Files(*.jpg *.png *.bmp);;All(*.*)"*/); if (!path.isEmpty()) { QFileInfo fileinfo(path); QString file_suffix = fileinfo.suffix(); staticDir = fileinfo.dir().absolutePath(); #if ST_CLIP_IMAGE cv::Mat m = cv::imread(path.toLocal8Bit().toStdString()); if (m.empty()) { emit sig_infoDisplay(QStringLiteral("读取失败,图片路径不正确!!")); return; } emit sig_infoDisplay(QStringLiteral("读取成功!!")); setRefPic(m); #else QImage pix; std::vector picRaw; //用于临时存储本地读取的图片 if (file_suffix == "jpg") { picRaw.clear(); std::ifstream ifile(path.toStdWString(), std::ios::binary); if (!ifile.is_open()) { QMESSAGEBOX_ERROR(CN("图片路径不对(目前不支持中文路径)!")); return; } ifile.seekg(0, std::ios::end); const auto size = static_cast(ifile.tellg()); ifile.seekg(0, std::ios::beg); picRaw.resize(size); ifile.read((char*)picRaw.data(), size); ifile.close(); //if (true) //{ pix.loadFromData(picRaw.data(), picRaw.size(), "JPG"); emit sig_infoDisplay(QStringLiteral("读取成功!!")); //} //else //{ // emit sig_infoDisplay(QStringLiteral("读取失败,图片路径不正确(目前尚不支持中文路径)!!")); //} } else if (file_suffix == "bmp") { picRaw.clear(); cv::Mat m = cv::imread(path.toLocal8Bit().toStdString()); if (!m.empty()) { cv::imencode(".jpg", m, picRaw); pix.loadFromData(picRaw.data(), picRaw.size(), "JPG"); emit sig_infoDisplay(QStringLiteral("读取成功!!")); } else { emit sig_infoDisplay(QStringLiteral("读取失败,图片路径不正确!!")); } } else { emit sig_infoDisplay(QStringLiteral("读取失败,格式暂不支持!!")); return; } setRefPic(pix, picRaw); #endif // ST_CLIP_IMAGE } else { emit sig_infoDisplay(QStringLiteral("读取失败,路径为空!!")); } } void Widget::on_BTN_OpenImageDet_clicked() { static QString staticDir = " "; clearRltInfo(); QString path = QFileDialog::getOpenFileName(this, QStringLiteral("打开图片(尚不支持中文路径)"), staticDir, "Image Files(*.jpg *.bmp);;All(*.*)"/*"Image Files(*.jpg *.png *.bmp);;All(*.*)"*/); if (!path.isEmpty()) { QFileInfo fileinfo(path); staticDir = fileinfo.dir().absolutePath(); #if ST_CLIP_IMAGE cv::Mat m = cv::imread(path.toLocal8Bit().toStdString()); if (m.empty()) { emit sig_infoDisplay(QStringLiteral("读取失败,图片路径不正确!!")); return; } emit sig_infoDisplay(QStringLiteral("读取成功!!")); setDetPic(m); #else QImage pix; std::vector picRaw; //用于临时存储本地读取的图片 QFileInfo fileinfo(path); QString file_suffix = fileinfo.suffix(); cv::Mat m; if (file_suffix == "jpg") { picRaw.clear(); std::ifstream ifile(path.toStdWString(), std::ios::binary); if (!ifile.is_open()) { QMESSAGEBOX_ERROR(CN("图片路径不对(目前不支持中文路径)!")); return; } ifile.seekg(0, std::ios::end); const auto size = static_cast(ifile.tellg()); ifile.seekg(0, std::ios::beg); picRaw.resize(size); ifile.read((char*)picRaw.data(), size); ifile.close(); //if (true) //{ pix.loadFromData(picRaw.data(), picRaw.size(), "JPG"); m = qImage_to_cvMat(pix); //m_PicShow = &pix; emit sig_infoDisplay(QStringLiteral("读取成功!!")); //} //else //{ // emit sig_infoDisplay(QStringLiteral("读取失败,图片路径不正确(目前尚不支持中文路径)!!")); //} } else if (file_suffix == "bmp") { picRaw.clear(); m = cv::imread(path.toLocal8Bit().toStdString(), cv::IMREAD_UNCHANGED); if (!m.empty()) { cv::imencode(".jpg", m, picRaw); pix.loadFromData(picRaw.data(), picRaw.size(), "JPG"); emit sig_infoDisplay(QStringLiteral("读取成功!!")); } else { emit sig_infoDisplay(QStringLiteral("读取失败,图片路径不正确!!")); } } else { emit sig_infoDisplay(QStringLiteral("读取失败,格式暂不支持!!")); return; } //showqImageSource(pix); setDetPic(m, picRaw); #endif // ST_CLIP_IMAGE } else { emit sig_infoDisplay(QStringLiteral("读取失败,路径为空!!")); } } void Widget::on_BTN_TakePhotoRef_clicked() { clearRltInfo(); if (!DataVar::g_isCamConnected) { QMESSAGEBOX_ERROR(CN("尚未连接接相机!")); return; } cv::Mat img; int ret = 0; if (DataVar::g_camTriggerMode == DataVar::SoftTriggerMode) //软触发模式 { ret = DataVar::g_camera->takeSingleImage(img); } else if (DataVar::g_camTriggerMode == DataVar::VideoStreamMode) { DataVar::g_camRealTimeShowMode = 0; for (size_t i = 0; i < 50; i++) { if (DataVar::g_imgsQueue.pop(img)) break; else QThread::msleep(20); } DataVar::g_camRealTimeShowMode = 1; } else { QMESSAGEBOX_ERROR(CN("现将相机配置为视频或者软触发模式!")); return; } if (ret != 0 || img.empty()) { emit sig_infoDisplay(QStringLiteral("相机拍照失败!!")); return; } #if ST_CLIP_IMAGE setRefPic(img); #else std::vector t; cv::imencode(".jpg", img, t); setRefPic(cvMat_To_qImage(img), t); #endif // ST_CLIP_IMAGE } void Widget::on_BTN_AlgDetect_clicked() { clearRltInfo(); ui->BTN_AlgDetect->setEnabled(false); if (DataVar::instance()->getPicRefWarp()->isNull()) { QMESSAGEBOX_ERROR(CN("请设定参考图!")); ui->BTN_AlgDetect->setEnabled(true); return; } if (ui->RBT_CameraMode->isChecked())//相机模式 { if (!DataVar::g_isCamConnected) { QMESSAGEBOX_ERROR(CN("尚未连接接相机!")); return; } cv::Mat img; if (DataVar::g_camTriggerMode == DataVar::SoftTriggerMode) { int ret = DataVar::g_camera->takeSingleImage(img); if (ret != 0 || img.empty()) { emit sig_infoDisplay(QStringLiteral("相机拍照失败!!")); ui->BTN_AlgDetect->setEnabled(true); return; } } else if(DataVar::g_camTriggerMode == DataVar::VideoStreamMode) { DataVar::g_camRealTimeShowMode = 0; for (size_t i = 0; i < 50; i++) { if (DataVar::g_imgsQueue.pop(img)) break; else QThread::msleep(20); } DataVar::g_camRealTimeShowMode = 1; } else { QMESSAGEBOX_WARN(CN("手动检测请配置相机为软触发或视频模式!")); ui->BTN_AlgDetect->setEnabled(true); return; } if (img.empty()) { QMESSAGEBOX_ERROR(CN("检测图获取失败!")); ui->BTN_AlgDetect->setEnabled(true); return; } #if ST_CLIP_IMAGE setDetPic(img); #else std::vector t; cv::imencode(".jpg", img, t); setDetPic(img, t); #endif // ST_CLIP_IMAGE } if (DataVar::instance()->getPicDet()->isNull()) { QMESSAGEBOX_ERROR(CN("检测图为空!")); ui->BTN_AlgDetect->setEnabled(true); return; } PostImg();//向服务器发送参考图和检测图 //ui->BTN_AlgDetect->setEnabled(true); } void Widget::on_BTN_Preprocess_clicked() { PreprocessWindow T(this); T.exec(); } void Widget::on_comboBox_activated(int index) { if(index == 1) { //ui->graphicsView->ROIShow(true); } else { //ui->graphicsView->ROIShow(false); } } void Widget::on_BTN_SaveImage_clicked() { QDateTime current_time = QDateTime::currentDateTime(); QString currentTime = current_time.toString("yyyyMMddhhmm"); static QString folder_name("ResultsImages"); //要创建的文件夹名称 static QDir RltImageDir(QDir::currentPath()); //初始化dir为当前目录 if (!m_picShow->isNull()) { if (!RltImageDir.exists(folder_name)) RltImageDir.mkdir(folder_name); QString savename = RltImageDir.absolutePath()+ "/"+folder_name+"/ " + currentTime + ".jpg"; m_picShow->save(savename.toStdString().data(), "JPG"); } } void Widget::saveRltImage() { QDateTime current_time = QDateTime::currentDateTime(); QString currentTime = current_time.toString("yyyyMMddhhmm"); static QString folder_name("ResultsImages"); //要创建的文件夹名称 static QDir RltImageDir(QDir::currentPath()); //初始化dir为当前目录 if (!(DataVar::instance()->getPicDealed()->isNull())) { if (!RltImageDir.exists(folder_name)) RltImageDir.mkdir(folder_name); QString savename = RltImageDir.absolutePath() + "/" + folder_name + "/ " + currentTime + ".jpg"; DataVar::instance()->getPicDealed()->save(savename.toStdString().data(), "JPG"); } } void Widget::clearRltInfo() { ui->TWG_resulrInfo->clearContents(); //int nRowCount = ui->TWG_resulrInfo->rowCount(); //for (int row = 0; row < nRowCount; row++) //{ // ui->TWG_resulrInfo->removeRow(0); //} DataVar::instance()->clearErrorRects(); } void Widget::on_BTN_ConfigCamera_clicked() { ui->LABEL_realTime->clear();//清空显示窗口 DataVar::instance()->g_frmCamParam->showNormal(); } void Widget::on_RectAlgChangedDet(QRect r) { } void Widget::on_RectAlgChangedRef(QRect r) { m_roiAlgRef = r; calRoiAlgDetFromRef(); } void Widget::slot_TWG_resulrInfo_Clicked(int row , int col) { //QTableWidgetItem* it = ui->TWG_resulrInfo->item(row, 1); //QString txt = it->text(); //QStringList ql = txt.split(","); //ui->label_source->slot_setRoiRect(QRect(ql[0].toInt(), ql[1].toInt(),ql[2].toInt(), ql[3].toInt())); } void Widget::slot_TWG_resulrInfo_SelectChanged() { if (DataVar::g_winShowMode & 2) { QTableWidgetItem* it = ui->TWG_resulrInfo->item(ui->TWG_resulrInfo->currentRow(), 1); if (it) { QString txt = it->text(); QStringList ql = txt.split(","); ui->label_source->slot_moveRoiRect(QRect(ql[0].toInt(), ql[1].toInt(), ql[2].toInt(), ql[3].toInt()).center()); ui->TWG_resulrInfo->setFocus(); //获取焦点 } } } void Widget::on_BTN_Close_clicked() { this->close(); } void Widget::on_BTN_Min_clicked() { //this->setWindowState(Qt::WindowMinimized); this->showMinimized(); } void Widget::on_BTN_Max_clicked() { if (this->windowState() == Qt::WindowMaximized) { this->showNormal(); //this->setWindowState(Qt::WindowNoState); } else { //this->setWindowState(Qt::WindowMaximized); this->showMaximized(); } } void Widget::changeCamOrFileMode() { if (ui->RBT_CameraMode->isChecked()) { DataVar::g_camOrFileMode = 0; ui->BTN_OpenImageRef->setEnabled(false); ui->BTN_OpenImageDet->setEnabled(false); ui->BTN_ConfigCamera->setEnabled(true); } else { DataVar::g_camOrFileMode = 1; ui->BTN_OpenImageRef->setEnabled(true); ui->BTN_OpenImageDet->setEnabled(true); ui->BTN_ConfigCamera->setEnabled(false); } } void Widget::realTimeShowImage() { //为了保证算法取图引起相片资源竞争,g_imgsQueue里面经常留一张图片 if (DataVar::g_camRealTimeShowMode == 1) { cv::Mat src; if (DataVar::g_imgsQueue.pop(src)) { if (!src.empty()) { updateImageScale(ui->LABEL_realTime, src); } } } } void Widget::matchAndRunAlg() { //setDetPicInner(); if (DataVar::g_camOrFileMode == 0)//相机模式 { cv::Mat img; if (!DataVar::g_imgsQueue.pop(img)) { emit sig_algReady(); return; } if (DataVar::instance()->getPicRefWarp()->isNull()) { QMESSAGEBOX_ERROR(CN("请先设定参考图!")); emit sig_algReady(); return; } #if ST_CLIP_IMAGE setDetPic(img); #else //std::vector t; //cv::imencode(".jpg", img, t); //setDetPic(img, t); #endif // ST_CLIP_IMAGE } if (DataVar::instance()->getPicDet()->isNull()) { QMESSAGEBOX_ERROR(CN("检测图设置异常!")); emit sig_algReady(); return; } PostImg();//向服务器发送参考图和检测图 ui->BTN_AlgDetect->setEnabled(false); }