#include "QtWidgetsApplication.h" QtWidgetsApplication::QtWidgetsApplication(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); // 获取 控制系统 单例并初始化 Mycontrol::getInstance().init(); //相机需要的显示控件 m_scene = new QGraphicsScene(this); ui.imgView->setScene(m_scene); //保存路径 ui.edtSaveDir->setText("D:/"); //TCT检测显示需要 tct_pixmapItem = new QGraphicsPixmapItem(tct_pixmap); tct_scene = new QGraphicsScene(this); tct_scene->addItem(tct_pixmapItem); //TCT模型处理的线程 my_TCT = new TCT(this); m_infQthread = new QThread(nullptr); my_TCT->moveToThread(m_infQthread); //TCT模型处理需要的信号与槽 connect(this, &QtWidgetsApplication::emit_img, my_TCT, &TCT::main_module); connect(my_TCT, &TCT::em_img, this, &QtWidgetsApplication::input_img); m_infQthread->start(); //定时器定时获取当前位置 QTimer* timer = new QTimer(this); timer->setInterval(50); // 设置定时器间隔为 50 毫秒 timer->setSingleShot(false); // 非单次触发,持续运行 connect(timer, &QTimer::timeout, [this]() { Mycontrol& Mycontrol = Mycontrol::getInstance(); ui.m_xpos->setValue(Mycontrol::getInstance().getXPos()); ui.m_ypos->setValue(Mycontrol::getInstance().getYPos()); ui.m_zpos->setValue(Mycontrol::getInstance().getZPos()); }); timer->start(); } QtWidgetsApplication::~QtWidgetsApplication() { } //选择相机 void QtWidgetsApplication::on_pb_camera_clicked() { QString currentText = ui.CameraBox->currentText(); // 获取文本 if (currentText == "haikang camera") { // 创建相机线程,和信号与槽 cam_thread = new QThread(this); Hacm_worker = new haikang(this); Hacm_worker->moveToThread(cam_thread); connect(cam_thread, &QThread::started, Hacm_worker, &haikang::GrabThreadProcess); //connect(Hacm_worker, &haikang::img_redy, this, &QtWidgetsApplication::do_hai_img_redy); //弃用 m_hwndDisplay = (HWND)ui.imgView->winId();//弃用 connect(cam_thread, &QThread::finished, Hacm_worker, &haikang::finish); connect(Hacm_worker, &haikang::img_to, this, &QtWidgetsApplication::hai_img_redy); cam_thread->start(); setSlideSpinboxCheckboxSync(); } if (currentText == "flir camera") { qRegisterMetaType("ImagePtr"); // 创建相机线程,和信号与槽 cam_thread = new QThread(this); cam_worker = new M_camera(nullptr); cam_worker->moveToThread(cam_thread); connect(cam_thread, &QThread::started, cam_worker, &M_camera::do_start);//线程开始,让相机初始化 connect(cam_worker, &M_camera::img_redy, this, &QtWidgetsApplication::do_img_redy); cam_thread->start(); //让曝光,增益的Slide和Spinbox同步 setSlideSpinboxCheckboxSync(); } } // 将海康相机传回来的图片进行显示 void QtWidgetsApplication::hai_img_redy(QImage image, void* handle) { hikimage = image; //往tct里面送的时候用 HK_handle = handle; //相机句柄 m_scene->clear(); // 清除旧图像 QPixmap pixmap = QPixmap::fromImage(image); pixmapItem = m_scene->addPixmap(pixmap); ui.imgView->fitInView(pixmapItem, Qt::KeepAspectRatio); ui.imgView->setScene(m_scene); ui.imgView->show(); } //将海康相机传回来的图片进行显示 //SB处理办法 void QtWidgetsApplication::do_hai_img_redy(MV_FRAME_OUT stImageInfo, void *handle) { //HK_handle = handle; //MV_DISPLAY_FRAME_INFO stDisplayInfo = {0}; //stDisplayInfo.hWnd = m_hwndDisplay; //显示的句柄 这种显示方式相当于绑定句柄 //stDisplayInfo.pData = stImageInfo.pBufAddr; //stDisplayInfo.nDataLen = stImageInfo.stFrameInfo.nFrameLen; //stDisplayInfo.nWidth = stImageInfo.stFrameInfo.nWidth; //stDisplayInfo.nHeight = stImageInfo.stFrameInfo.nHeight; //stDisplayInfo.enPixelType = stImageInfo.stFrameInfo.enPixelType; //MV_CC_DisplayOneFrame(handle, &stDisplayInfo); //MV_CC_FreeImageBuffer(handle, &stImageInfo); } //将flir相机传回来的图片进行显示 void QtWidgetsApplication::do_img_redy(ImagePtr pResultImage) { const size_t width = pResultImage->GetWidth(); const size_t height = pResultImage->GetHeight(); const unsigned char* pData = (const unsigned char*)pResultImage->GetData(); // 根据像素格式创建 QImage QImage qImage(pData, static_cast(width), static_cast(height), static_cast(width * pResultImage->GetBitsPerPixel() / 8), QImage::Format_RGB888); // 根据实际情况调整格式 m_scene->clear(); // 清除旧图像 QPixmap pixmap = QPixmap::fromImage(qImage); pixmapItem = m_scene->addPixmap(pixmap); ui.imgView->fitInView(pixmapItem, Qt::KeepAspectRatio); ui.imgView->setScene(m_scene); ui.imgView->show(); } int QtWidgetsApplication::resetExposure() { Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap(); CEnumerationPtr exposureAuto = nodeMap.GetNode("ExposureAuto"); exposureAuto->SetIntValue(exposureAuto->GetEntryByName("Continuous")->GetValue()); return 0; } int QtWidgetsApplication::configureExposure(double exposure) { Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap(); CEnumerationPtr exposureAuto = nodeMap.GetNode("ExposureAuto"); exposureAuto->SetIntValue(exposureAuto->GetEntryByName("Off")->GetValue()); CEnumerationPtr exposureMode = nodeMap.GetNode("ExposureMode"); exposureMode->SetIntValue(exposureMode->GetEntryByName("Timed")->GetValue()); CFloatPtr exposureTime = nodeMap.GetNode("ExposureTime"); exposureTime->SetValue(exposure); return 0; } void QtWidgetsApplication::setSlideSpinboxCheckboxSync() { QString currentText = ui.CameraBox->currentText(); if (currentText == "flir camera") { // Exposure connect(ui.sldExposure, &QSlider::valueChanged, ui.spinExposure, [this](int sliderValue) { ui.spinExposure->setValue(static_cast(sliderValue)); }); connect(ui.spinExposure, QOverload::of(&QDoubleSpinBox::valueChanged), ui.sldExposure, [this](double spinValue) { ui.sldExposure->setValue(static_cast(spinValue)); configureExposure(spinValue); }); connect(ui.chkExposure, &QCheckBox::toggled, [this](bool checked) { bool isEnabled = !checked; ui.spinExposure->setEnabled(isEnabled); ui.sldExposure->setEnabled(isEnabled); resetExposure(); }); // Gain connect(ui.sldGain, &QSlider::valueChanged, ui.spinGain, [this](int sliderValue) { ui.spinGain->setValue(static_cast(sliderValue) / 100.0); }); connect(ui.spinGain, QOverload::of(&QDoubleSpinBox::valueChanged), ui.sldGain, [this](double spinValue) { ui.sldGain->setValue(static_cast(spinValue * 100)); configureGain(spinValue); }); connect(ui.chkGain, &QCheckBox::toggled, [this](bool checked) { bool isEnabled = !checked; ui.spinGain->setEnabled(isEnabled); ui.sldGain->setEnabled(isEnabled); resetGain(); }); } if (currentText =="haikang camera") { // Exposure connect(ui.sldExposure, &QSlider::valueChanged, ui.spinExposure, [this](int sliderValue) { ui.spinExposure->setValue(static_cast(sliderValue)); }); connect(ui.spinExposure, QOverload::of(&QDoubleSpinBox::valueChanged), ui.sldExposure, [this](double spinValue) { ui.sldExposure->setValue(static_cast(spinValue)); HK_configureExposure(spinValue); }); connect(ui.chkExposure, &QCheckBox::toggled, [this](bool checked) { bool isEnabled = !checked; ui.spinExposure->setEnabled(isEnabled); ui.sldExposure->setEnabled(isEnabled); HK_resetExposure(); }); // Gain connect(ui.sldGain, &QSlider::valueChanged, ui.spinGain, [this](int sliderValue) { ui.spinGain->setValue(static_cast(sliderValue) / 100.0); }); connect(ui.spinGain, QOverload::of(&QDoubleSpinBox::valueChanged), ui.sldGain, [this](double spinValue) { ui.sldGain->setValue(static_cast(spinValue * 100)); HK_configureGain(spinValue); }); connect(ui.chkGain, &QCheckBox::toggled, [this](bool checked) { bool isEnabled = !checked; ui.spinGain->setEnabled(isEnabled); ui.sldGain->setEnabled(isEnabled); HK_resetGain(); }); } } void QtWidgetsApplication::HK_resetGain() { MV_CC_SetExposureAutoMode(HK_handle, 2); } void QtWidgetsApplication::HK_resetExposure() { MV_CC_SetGain(HK_handle, 2); } void QtWidgetsApplication::HK_configureExposure(double exposure) { MV_CC_SetFloatValue(HK_handle, "ExposureTime", exposure); } void QtWidgetsApplication::HK_configureGain(double gain) { MV_CC_SetFloatValue(HK_handle, "Gain", gain); } int QtWidgetsApplication::configureGain(double gain) { Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap(); CEnumerationPtr gainAuto = nodeMap.GetNode("GainAuto"); gainAuto->SetIntValue(gainAuto->GetEntryByName("Off")->GetValue()); CFloatPtr gainValue = nodeMap.GetNode("Gain"); gainValue->SetValue(gain); return 0; } int QtWidgetsApplication::resetGain() { Spinnaker::GenApi::INodeMap& nodeMap = cam_worker->pCam->GetNodeMap(); CEnumerationPtr gainAuto = nodeMap.GetNode("GainAuto"); gainAuto->SetIntValue(gainAuto->GetEntryByName("Continuous")->GetValue()); return 0; } //单张图片的保存 void QtWidgetsApplication::on_btnSingleImageSave_clicked() { QString currentText = ui.CameraBox->currentText(); if (currentText == "flir camera") { qDebug() << "Single image save clicked"; QString fileName = QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); QString absPath = ui.edtSaveDir->text() + "/" + fileName + ".tif"; qDebug() << "Save path: " << absPath << ""; ImagePtr pImage = cam_worker->pCam->GetNextImage(1000); if (pImage->IsIncomplete()) { qDebug() << "Image incomplete in 1s: " << Image::GetImageStatusDescription(pImage->GetImageStatus()) << "..."; } ImagePtr pConvertedImage = processor.Convert(pImage, PixelFormat_RGB8); pConvertedImage->Save(absPath.toStdString().c_str()); } if (currentText == "haikang camera") { } } //选择保存路径 void QtWidgetsApplication::on_btnSaveDir_clicked() { qDebug() << "Choose save dir clicked"; QString dirPath = QFileDialog::getExistingDirectory( this, QString::fromUtf8(u8"请选择图像保存路径") ); qDebug() << "Choose save dir: " << dirPath << ""; ui.edtSaveDir->setText(dirPath); } // 将TCT检测的图片进行显示 void QtWidgetsApplication::input_img(QImage image) { in_image = image; // 显示经过网络检测后的图片 this->ui.TCT_View->setScene(tct_scene); tct_pixmap = QPixmap::fromImage(in_image); tct_pixmapItem = tct_scene->addPixmap(tct_pixmap); // 自适应显示图片 ui.TCT_View->fitInView(tct_pixmapItem, Qt::KeepAspectRatio); ui.TCT_View->setRenderHint(QPainter::Antialiasing); // 抗锯齿 ui.TCT_View->setDragMode(QGraphicsView::ScrollHandDrag); // 启动手动拖动模式 ui.TCT_View->show(); } // 将ImagePtr转换成QImage QImage convertToQImage(const ImagePtr& pImage) { // 获取图像尺寸 int width = pImage->GetWidth(); int height = pImage->GetHeight(); // 获取像素数据指针(假设为 uchar* 类型) const uchar* pData = reinterpret_cast(pImage->GetData()); // 获取每行的字节数(步长) int stride = width * 3; // 假设存在此方法,若不存在可设为 width * 3 // 构造 QImage QImage qImage(pData, width, height, stride, QImage::Format_RGB888); // 返回深拷贝,避免原始图像数据被释放导致 QImage 无效 return qImage.copy(); } // 将相机图片输入到网络的线程中 void QtWidgetsApplication::on_pb_model_clicked() { /*QString fileName = QFileDialog::getOpenFileName(this, "选择图片", "D:/TCT_down/dataset/test/images", "Images (*.png *.jpg)"); QImage image(fileName);*/ QString currentText = ui.CameraBox->currentText(); if (currentText == "flir camera") { ImagePtr pImage = cam_worker->pCam->GetNextImage(1000); if (pImage->IsIncomplete()) { qDebug() << "Image incomplete in 1s: " << Image::GetImageStatusDescription(pImage->GetImageStatus()) << "..."; } ImagePtr pConvertedImage = processor.Convert(pImage, PixelFormat_RGB8); QImage image = convertToQImage(pConvertedImage); emit emit_img(image); } if (currentText == "haikang camera") { emit emit_img(hikimage); } } // 运动控制 void QtWidgetsApplication::on_btnUp_clicked() { double zdis = ui.spinZDis->value(); qDebug() << "up clicked, move up: " << zdis << "um"; Mycontrol::getInstance().moveBy(3, zdis * -1e-3); } void QtWidgetsApplication::on_btnDown_clicked() { double zdis = ui.spinZDis->value(); qDebug() << "up clicked, move up: " << zdis << "um"; Mycontrol::getInstance().moveBy(3, -zdis * -1e-3); } void QtWidgetsApplication::on_btnLeft_clicked() { double xdis = ui.spinXDis->value(); qDebug() << "up clicked, move up: " << xdis << "um"; Mycontrol::getInstance().moveBy(2, -xdis * -1e-3); } void QtWidgetsApplication::on_btnRight_clicked() { double xdis = ui.spinXDis->value(); qDebug() << "up clicked, move up: " << xdis << "um"; Mycontrol::getInstance().moveBy(2, xdis * -1e-3); } void QtWidgetsApplication::on_btnForward_clicked() { double ydis = ui.spinYDis->value(); qDebug() << "up clicked, move up: " << ydis << "um"; Mycontrol::getInstance().moveBy(1, -ydis * -1e-3); } void QtWidgetsApplication::on_btnBackward_clicked() { double ydis = ui.spinYDis->value(); qDebug() << "up clicked, move up: " << ydis << "um"; Mycontrol::getInstance().moveBy(1, ydis * -1e-3); } double sharpnessSobel(cv::Mat image) { cv::Mat roi = image(cv::Rect(968, 768, 512, 512)); cv::Mat gray; cv::cvtColor(roi, gray, cv::COLOR_BGR2GRAY); cv::GaussianBlur(gray, gray, cv::Size(5, 5), 0); cv::Mat sobelx, sobely; cv::Sobel(gray, sobelx, CV_64F, 1, 0, 3); cv::Sobel(gray, sobely, CV_64F, 0, 1, 3); cv::Mat magnitude; cv::magnitude(sobelx, sobely, magnitude); return cv::mean(magnitude)[0]; }