OpenCV图像处理->鼠标移动区域放大

本文介绍了一个使用OpenCV实现的鼠标交互示例,当鼠标移动时,会在图像上绘制一个绿色的矩形框,并根据鼠标位置调整其大小。该示例展示了如何使用cvSetMouseCallback函数设置鼠标回调,以及如何利用cvRectangle进行绘图。


调用OpenCV函数里面的鼠标响应函数:

	cvSetMouseCallback( "img", on_mouse, 0 );

鼠标响应具体实现的函数:
int foo=100;//调节窗口大小,也称为比例系数。
void on_mouse( int event, int x, int y, int flags, void* ustc)
{
	if( event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))
	{
		cvCopy(org,img);
		CvPoint p0;
		CvPoint p1;
		if(x<foo)
		{
			if(y<foo)
			{
				p0=cvPoint(0,0);
				p1=cvPoint(2*foo,2*foo);
			}
			else if(y>img->height-foo)
			{ 
				p0=cvPoint(0,img->height-2*foo);
				p1=cvPoint(2*foo,img->height);
			}
			else
			{
				p0=cvPoint(0,y-foo);
				p1=cvPoint(2*foo,y+foo);
			}
		}
		else if(x>img->width-foo)
		{
			if(y<foo)
			{
				p0=cvPoint(img->width-2*foo,0);
				p1=cvPoint(img->width,2*foo);
			}
			else if(y>img->height-foo)
			{ 
				p0=cvPoint(img->width-2*foo,img->height-2*foo);
				p1=cvPoint(img->width,img->height);
			}
			else
			{
				p0=cvPoint(img->width-2*foo,y-foo);
				p1=cvPoint(img->width,y+foo);
			}
		}
		else
		{
			if(y<foo)
			{
				p0=cvPoint(x-foo,0);
				p1=cvPoint(x+foo,2*foo);
			}
			else if(y>img->height-foo)
			{ 
				p0=cvPoint(x-foo,img->height-2*foo);
				p1=cvPoint(x+foo,img->height);
			}
			else
			{
				p0=cvPoint(x-foo,y-foo);
				p1=cvPoint(x+foo,y+foo);
			}
		}
		cvRectangle(img,p0,p1,CV_RGB(0,255,0));
		cvSetImageROI(org,cvRect(p0.x,p0.y,p1.x-p0.x,p1.y-p0.y));//设置感兴趣区域
		cvResize(org,dst);//大小重置
		cvResetImageROI(org);
		cvShowImage( "img", img );
		cvShowImage("dst",dst);
	}
}


#include"mainwindow.h" #include "ui_mainwindow.h" #include <QFileDialog> #include <QDir> #include <QMessageBox> #include <QGraphicsScene> #include <QGraphicsPixmapItem> #include <QSettings> #include <QTextStream> #include<QDebug> #include <QWheelEvent> #include <QMouseEvent> #include <QScrollBar> #include <QGraphicsLineItem> //#include <opencv2/opencv.hpp> #include <QString> #include <QDebug> #include <QDesktopServices> #include <QUrl> #include <QFileSystemModel> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 初始化参数 toothParams.Init();//矫正参数 laserParams.Init();//激光参数 currentPixmapItem = nullptr; currentLineItem = nullptr; currentScale = 1.0; isDragging = false; // 设置树形视图 //ui->treeWidget->setHeaderLabel("文件夹结构"); //qDebug() << "Original:" << "文件" << "UTF-8:" ; // 设置图形视图的属性 //ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag); ui->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); ui->graphicsView->setResizeAnchor(QGraphicsView::AnchorUnderMouse);//设置视图组件本身大小改变时的锚点 ui->graphicsView->setRenderHint(QPainter::Antialiasing); ui->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); // 连接信号槽 connect(ui->treeWidget,&QTreeWidget::itemClicked,this,&MainWindow::on_treeWidget_itemClicked); } MainWindow::~MainWindow() { delete ui; } // void listCameras() { // for (int i = 0;; ++i) { // cv::VideoCapture cap(i); // if (!cap.isOpened()) { // break; // } // qDebug() << "Found camera:" << i; // cap.release(); // } // } void MainWindow::on_browseButton_clicked() { QString folderPath = QFileDialog::getExistingDirectory(this, "选择标定文件夹"); if (!folderPath.isEmpty()) { currentFolderPath = folderPath; ui->folderPathEdit->setText(folderPath); updateTreeView(folderPath); } } void MainWindow::on_calibrateButton_clicked() { /* ---------- 1. 基础检查 ---------- */ if (currentFolderPath.isEmpty()) { QMessageBox::warning(this, QString::fromUtf8("警告"), QString::fromUtf8("请先选择标定文件夹")); return; } if (ui->cameraNameEdit->text().trimmed().isEmpty()) { QMessageBox::warning(this, QString::fromUtf8("警告"), QString::fromUtf8("请输入相机名称")); return; } updateParametersFromUI(); /* ---------- 2. 参数合法性检查 ---------- */ if (laserParams.CameraWidth <= 0 || laserParams.CameraHeight <= 0 || laserParams.CameraFocal <= 0) { QMessageBox::warning(this, QString::fromUtf8("警告"), QString::fromUtf8("相机宽度、高度或焦距不能为 0")); return; } calibrationPoints.clear(); int validDirCount = 0; /* ---------- 3. 主循环 ---------- */ for (int disIndex = 60; disIndex < 400; disIndex += 10) { QString currDir = QDir(currentFolderPath).filePath(QString("%1_0").arg(disIndex)); QDir dir(currDir); if (!dir.exists()) { qDebug() << "跳过不存在的目录:" << currDir; continue; } QFileInfoList imgs = dir.entryInfoList(QStringList() << "*.bmp" << "*.jpg" << "*.png", QDir::Files); if (imgs.isEmpty()) { qDebug() << "目录无图像:" << currDir; continue; } ++validDirCount; QByteArray dirBA = currDir.toLocal8Bit(); char dirChar[512] = {0}; strncpy_s(dirChar, sizeof(dirChar) - 1, dirBA.constData(), _TRUNCATE); qDebug() << "DLL 输入路径:" << dirChar << "图像数量:" << imgs.size(); std::vector<ToothCalibPoint> vLineCaliPoint; bool ok = GetToothPositionModeOne(dirChar, toothParams, vLineCaliPoint); qDebug() << "GetToothPositionModeOne 返回:" << ok << "点数:" << vLineCaliPoint.size(); if (!ok || vLineCaliPoint.empty()) continue; double left = 0, right = 0; for (const auto &p : vLineCaliPoint) { if (p.PointMode == 1) left = p.CameraW; if (p.PointMode == 2) right = p.CameraW; } if (left > 0 && right > 0) toothParams.CenterPos = (left + right) / 2.0; QVector<ToothCalibPoint> qv; qv.reserve(int(vLineCaliPoint.size())); for (const auto &p : vLineCaliPoint) qv.append(p); calibrationPoints.append(qv); } /* ---------- 4. 检查有效目录 ---------- */ if (validDirCount == 0 || calibrationPoints.isEmpty()) { QMessageBox::warning(this, QString::fromUtf8("警告"), QString::fromUtf8("未找到任何有效标定目录或标定点,请检查数据")); return; } /* ---------- 5. 保存 tooth.txt ---------- */ QString saveTxt = QDir(currentFolderPath).filePath("tooth.txt"); QFile file(saveTxt); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning(this, QString::fromUtf8("错误"), QString::fromUtf8("无法创建标定文件")); return; } QTextStream out(&file); #if QT_VERSION < QT_VERSION_CHECK(6,0,0) out.setCodec("UTF-8"); #else out.setEncoding(QStringConverter::Utf8); #endif int total = 0; for (const auto &vec : calibrationPoints) for (const auto &p : vec) { out << QString::number(p.CameraW, 'f', 3) << ',' << QString::number(p.CameraH, 'f', 3) << ',' << QString::number(p.WorldX, 'f', 3) << ',' << QString::number(p.WorldZ, 'f', 3) << ',' << p.FileName << ";\n"; ++total; } file.close(); qDebug() << "已保存" << total << "点到" << saveTxt; /* ---------- 6. 激光线标定 ---------- */ LaserLineModelResult res; res.Init(); // 设置输出目录为当前选择的文件夹下的"生成的标注结果"子文件夹 QString outputDir = QDir(currentFolderPath).filePath("生成的标注结果"); QDir().mkpath(outputDir); // 确保输出目录存在 QString cameraName = ui->cameraNameEdit->text().trimmed(); if (cameraName.isEmpty()) { cameraName = "default_camera"; } // 设置输出文件路径 QString dllPath = QDir(outputDir).filePath(cameraName + "-deep3.dll"); QString pcImagePath = QDir(outputDir).filePath(cameraName + "-pc.jpg"); QString rcImagePath = QDir(outputDir).filePath(cameraName + "-rc.jpg"); QString xImagePath = QDir(outputDir).filePath(cameraName + "-X.png"); QString zImagePath = QDir(outputDir).filePath(cameraName + "-Z.png"); qDebug()<<dllPath; QByteArray txtBA = saveTxt.toUtf8(); QByteArray nameBA = cameraName.toUtf8(); QByteArray dllDirBA = outputDir.toUtf8(); strncpy_s(laserParams.CalibPointFileName, sizeof(laserParams.CalibPointFileName) - 1, txtBA.constData(), _TRUNCATE); strncpy_s(laserParams.CameraName, sizeof(laserParams.CameraName) - 1, nameBA.constData(), _TRUNCATE); strncpy_s(res.CalibResultDir, sizeof(res.CalibResultDir) - 1, dllDirBA.constData(), _TRUNCATE); laserParams.MeasurePrecision = ui->precisionSpinBox->value(); // 调用标定函数 bool calibrationSuccess = GetLaserLineCalibUseLcModeThree(laserParams, res); if (calibrationSuccess) { /* ---------- 7. 重命名和移动生成的文件 ---------- */ QString defaultDllPath = QDir(outputDir).filePath("deep3.dll"); QString defaultPcPath = QDir(outputDir).filePath("pc.jpg"); QString defaultRcPath = QDir(outputDir).filePath("rc.jpg"); QString defaultXPath = QDir(outputDir).filePath("X.png"); QString defaultZPath = QDir(outputDir).filePath("Z.png"); // 重命名文件 if (QFile::exists(defaultDllPath)) { QFile::rename(defaultDllPath, dllPath); } if (QFile::exists(defaultPcPath)) { QFile::rename(defaultPcPath, pcImagePath); } if (QFile::exists(defaultRcPath)) { QFile::rename(defaultRcPath, rcImagePath); } if (QFile::exists(defaultXPath)) { QFile::rename(defaultXPath, xImagePath); } if (QFile::exists(defaultZPath)) { QFile::rename(defaultZPath, zImagePath); } /* ---------- 8. 验证文件生成 ---------- */ bool allFilesGenerated = true; QStringList missingFiles; if (!QFile::exists(dllPath)) { allFilesGenerated = false; missingFiles << "DLL文件"; } if (!QFile::exists(pcImagePath)) { allFilesGenerated = false; missingFiles << "pc.jpg"; } if (!QFile::exists(rcImagePath)) { allFilesGenerated = false; missingFiles << "rc.jpg"; } if (!QFile::exists(xImagePath)) { allFilesGenerated = false; missingFiles << "X.png"; } if (!QFile::exists(zImagePath)) { allFilesGenerated = false; missingFiles << "Z.png"; } if (allFilesGenerated) { QMessageBox::information(this, QStringLiteral("完成"), QString::fromUtf8("标定完成!文件已生成在:%1").arg(outputDir)); // 可选:打开生成的文件夹 QDesktopServices::openUrl(QUrl::fromLocalFile(outputDir)); } else { QMessageBox::warning(this, QStringLiteral("部分完成"), QString::fromUtf8("标定完成,但缺少以下文件:%1\n请检查DLL输出路径。") .arg(missingFiles.join(", "))); } } else { QMessageBox::critical(this, QStringLiteral("错误"), QString::fromUtf8("标定失败!请检查输入参数和数据。")); } } void MainWindow::updateTreeView(const QString &folderPath) { ui->treeWidget->clear(); QDir dir(folderPath); if (!dir.exists()) return; // 添加文件夹和子文件夹 QTreeWidgetItem *rootItem = new QTreeWidgetItem(ui->treeWidget); rootItem->setText(0, dir.dirName()); rootItem->setData(0, Qt::UserRole, folderPath); // 遍历子文件夹 QFileInfoList folders = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); foreach (const QFileInfo &folderInfo, folders) { QTreeWidgetItem *folderItem = new QTreeWidgetItem(rootItem); folderItem->setText(0, folderInfo.fileName()); folderItem->setData(0, Qt::UserRole, folderInfo.absoluteFilePath()); // 添加图片文件 QDir subDir(folderInfo.absoluteFilePath()); QFileInfoList images = subDir.entryInfoList(QStringList() << "*.bmp" << "*.jpg" << "*.png", QDir::Files); foreach (const QFileInfo &imageInfo, images) { QTreeWidgetItem *imageItem = new QTreeWidgetItem(folderItem); imageItem->setText(0, imageInfo.fileName()); imageItem->setData(0, Qt::UserRole, imageInfo.absoluteFilePath()); } } ui->treeWidget->expandAll(); // 将文件夹和图片全部展示出 } // void MainWindow::on_calibrateButton_clicked() // { // if (currentFolderPath.isEmpty()) // { // QMessageBox::warning(this, QString::fromUtf8("警告"), QString::fromUtf8("请先选择文件夹")); // return; // } // // 更新参数 // updateParametersFromUI(); // // 执行标定过程 // calibrationPoints.clear(); // for (int disIndex = 60; disIndex < 400; disIndex += 10) { // std::vector<ToothCalibPoint> vLineCaliPoint; // // 使用一致的路径分隔符 // //QString currSingleFileDir = currentFolderPath + "/" + QString::number(disIndex) + "_0"; // std::string currSingleFileDir = currentFolderPath.toStdString() + "\\" + std::to_string(disIndex) + "_0"; // //qDebug() << "Current Single File Directory:" << currSingleFileDir; // // 检查目录是否存在 // /*QDir dir(currSingleFileDir); // if (!dir.exists()) { // qDebug() << "Directory does not exist:" << currSingleFileDir; // continue; // }*/ // // 检查目录中是否有图像文件 // /*QStringList images = dir.entryList(QStringList() << "*.bmp" << "*.jpg" << "*.png", QDir::Files); // if (images.isEmpty()) { // qDebug() << "No images found in directory:" << currSingleFileDir; // continue; // }*/ // //qDebug() << "Found" << images.size() << "images in directory"; // char currSingleFileDir_char[512]; // 假设 512 足够 // strcpy_s(currSingleFileDir_char, sizeof(currSingleFileDir_char), currSingleFileDir.c_str()); // // 转换为本地编码(确保与外部库兼容) // //QByteArray ba = currSingleFileDir.toLocal8Bit(); // //char currSingleFileDir_char[512]; // //strncpy_s(currSingleFileDir_char, sizeof(currSingleFileDir_char), ba.constData(), _TRUNCATE); // qDebug() << "Calling GetToothPositionModeOne with path:" << currSingleFileDir_char; // // 调用标定函数 // bool success = GetToothPositionModeOne(currSingleFileDir_char, toothParams, vLineCaliPoint); // qDebug() << "GetToothPositionModeOne result:" << success; // qDebug() << "vLineCaliPoint size:" << vLineCaliPoint.size(); // if (!vLineCaliPoint.empty()) { // double leftPos = 0; // double rightPos = 0; // for (auto& p : vLineCaliPoint) { // qDebug() << "Point mode:" << p.PointMode << "CameraW:" << p.CameraW; // if (p.PointMode == 1) leftPos = p.CameraW; // if (p.PointMode == 2) rightPos = p.CameraW; // } // if (leftPos > 0 && rightPos > 0) { // toothParams.CenterPos = (leftPos + rightPos) / 2.0; // qDebug() << "Calculated center position:" << toothParams.CenterPos; // } // QVector<ToothCalibPoint> qVector; // for (const auto& point : vLineCaliPoint) { // qVector.append(point); // } // calibrationPoints.append(qVector); // } else { // qDebug() << "No calibration points found for distance:" << disIndex; // } // } // // 保存标定文件 // QString saveTxtName = currentFolderPath + "/tooth.txt"; // QFile file(saveTxtName); // if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { // QTextStream out(&file); // // 设置编码为 UTF-8 // #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // out.setCodec("UTF-8"); // #else // out.setEncoding(QStringConverter::Utf8); // #endif // int pointCount = 0; // for (const auto& points : calibrationPoints) { // for (const auto& pt : points) { // out << QString::number(pt.CameraW, 'f', 3) << "," // << QString::number(pt.CameraH, 'f', 3) << "," // << QString::number(pt.WorldX, 'f', 3) << "," // << QString::number(pt.WorldZ, 'f', 3) << "," // << pt.FileName << ";\n"; // pointCount++; // } // } // file.close(); // qDebug() << "Saved" << pointCount << "calibration points to" << saveTxtName; // if (pointCount == 0) { // QMessageBox::warning(this, QString::fromUtf8("警告"), QString::fromUtf8("未找到任何标定点,请检查输入数据和参数设置")); // return; // } // } else { // qDebug() << "Failed to open file for writing:" << saveTxtName; // QMessageBox::warning(this, QString::fromUtf8("错误"), QString::fromUtf8("无法创建标定文件")); // return; // } // // 执行激光线标定 // LaserLineModelResult currResultOut; // currResultOut.Init(); // QByteArray ba1 = saveTxtName.toUtf8(); // strncpy_s(laserParams.CalibPointFileName, ba1.constData(), sizeof(laserParams.CalibPointFileName)); // QByteArray ba2 = ui->cameraNameEdit->text().toUtf8(); // strncpy_s(laserParams.CameraName, ba2.constData(), sizeof(laserParams.CameraName)); // QString cameraSaveDir = QApplication::applicationDirPath() + "/Calibrate/" + // ui->cameraNameEdit->text() + "_dll"; // QDir().mkpath(cameraSaveDir); // QByteArray ba3 = cameraSaveDir.toUtf8(); // strncpy_s(currResultOut.CalibResultDir, ba3.constData(), sizeof(currResultOut.CalibResultDir)); // currResultOut.MeasurePrecision = ui->precisionSpinBox->value(); // GetLaserLineCalibUseLcModeThree(laserParams, currResultOut); // QMessageBox::information(this, QStringLiteral("完成"), QString::fromLocal8Bit("标定完成!")); // } // void MainWindow::on_calibrateButton_clicked() // { // /* ---------- 1. 基础检查 ---------- */ // if (currentFolderPath.isEmpty()) // { // QMessageBox::warning(this, QString::fromUtf8("警告"), // QString::fromUtf8("请先选择标定文件夹")); // return; // } // if (ui->cameraNameEdit->text().trimmed().isEmpty()) // { // QMessageBox::warning(this, QString::fromUtf8("警告"), // QString::fromUtf8("请输入相机名称")); // return; // } // updateParametersFromUI(); // 把 UI 值读到 toothParams / laserParams // /* ---------- 2. 参数合法性检查 ---------- */ // if (laserParams.CameraWidth <= 0 || laserParams.CameraHeight <= 0 || // laserParams.CameraFocal <= 0) // { // QMessageBox::warning(this, QString::fromUtf8("警告"), // QString::fromUtf8("相机宽度、高度或焦距不能为 0")); // return; // } // calibrationPoints.clear(); // 清空旧数据 // int validDirCount = 0; // 统计有效目录数 // /* ---------- 3. 主循环 ---------- */ // for (int disIndex = 60; disIndex < 400; disIndex += 10) // { // QString currDir = QDir(currentFolderPath).filePath(QString("%1_0").arg(disIndex)); // // QString currDir = currentFolderPath.toStdString() + "\\" + std::to_string(disIndex); // QDir dir(currDir); // /* 3.1 目录是否存在 */ // if (!dir.exists()) // { // qDebug() << "跳过不存在的目录:" << currDir; // continue; // } // /* 3.2 是否有图像 */ // QFileInfoList imgs = dir.entryInfoList(QStringList() << "*.bmp" << "*.jpg" << "*.png", // QDir::Files); // if (imgs.isEmpty()) // { // qDebug() << "目录无图像:" << currDir; // continue; // } // ++validDirCount; // /* 3.3 准备 char* 路径 */ // QByteArray dirBA = currDir.toLocal8Bit(); // 本地编码,兼容 DLL // char dirChar[512] = {0}; // strncpy_s(dirChar, sizeof(dirChar) - 1, // dirBA.constData(), _TRUNCATE); // qDebug() << "DLL 输入路径:" << dirChar // << "图像数量:" << imgs.size(); // /* 3.4 调用 DLL */ // std::vector<ToothCalibPoint> vLineCaliPoint; // bool ok = GetToothPositionModeOne(dirChar, toothParams, vLineCaliPoint); // qDebug() << "GetToothPositionModeOne 返回:" << ok // << "点数:" << vLineCaliPoint.size(); // if (!ok || vLineCaliPoint.empty()) // continue; // /* 3.5 计算中心 & 转 Qt 容器 */ // double left = 0, right = 0; // for (const auto &p : vLineCaliPoint) // { // if (p.PointMode == 1) left = p.CameraW; // if (p.PointMode == 2) right = p.CameraW; // } // if (left > 0 && right > 0) // toothParams.CenterPos = (left + right) / 2.0; // QVector<ToothCalibPoint> qv; // qv.reserve(int(vLineCaliPoint.size())); // for (const auto &p : vLineCaliPoint) qv.append(p); // calibrationPoints.append(qv); // } // /* ---------- 4. 一个有效目录都没跑 ---------- */ // if (validDirCount == 0 || calibrationPoints.isEmpty()) // { // QMessageBox::warning(this, QString::fromUtf8("警告"), // QString::fromUtf8("未找到任何有效标定目录或标定点,请检查数据")); // return; // } // /* ---------- 5. 保存 tooth.txt ---------- */ // //QString saveTxt = QApplication::applicationDirPath() + "/resources/tooth.txt"; // QString saveTxt = QDir(currentFolderPath).filePath("tooth.txt"); // QFile file(saveTxt); // if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) // { // QMessageBox::warning(this, QString::fromUtf8("错误"), // QString::fromUtf8("无法创建标定文件")); // return; // } // QTextStream out(&file); // #if QT_VERSION < QT_VERSION_CHECK(6,0,0) // out.setCodec("UTF-8"); // #else // out.setEncoding(QStringConverter::Utf8); // #endif // int total = 0; // for (const auto &vec : calibrationPoints) // for (const auto &p : vec) // { // out << QString::number(p.CameraW, 'f', 3) << ',' // << QString::number(p.CameraH, 'f', 3) << ',' // << QString::number(p.WorldX, 'f', 3) << ',' // << QString::number(p.WorldZ, 'f', 3) << ',' // << p.FileName << ";\n"; // ++total; // } // file.close(); // qDebug() << "已保存" << total << "点到" << saveTxt; // /* ---------- 6. 激光线标定 ---------- */ // LaserLineModelResult res; // res.Init(); // /* 6.1 填充激光参数 & 输出路径 */ // QByteArray txtBA = saveTxt.toUtf8(); // QByteArray nameBA = ui->cameraNameEdit->text().toUtf8(); // QByteArray dirBA = (QApplication::applicationDirPath() // + "/Calibrate/" // + ui->cameraNameEdit->text() + "_dll").toUtf8(); // strncpy_s(laserParams.CalibPointFileName, // sizeof(laserParams.CalibPointFileName) - 1, // txtBA.constData(), _TRUNCATE); // strncpy_s(laserParams.CameraName, // sizeof(laserParams.CameraName) - 1, // nameBA.constData(), _TRUNCATE); // strncpy_s(res.CalibResultDir, // sizeof(res.CalibResultDir) - 1, // dirBA.constData(), _TRUNCATE); // laserParams.MeasurePrecision = ui->precisionSpinBox->value(); // QDir().mkpath(QString::fromUtf8(dirBA)); // 确保输出目录存在 // GetLaserLineCalibUseLcModeThree(laserParams, res); // QMessageBox::information(this, QStringLiteral("完成"), // QString::fromUtf8("标定完成!")); // } //当树形控件中的某个项目被点击时触发,用于加载或显示被选中的内容 void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int column) { Q_UNUSED(column); QString filePath = item->data(0, Qt::UserRole).toString(); if (QFileInfo(filePath).isFile()) { // 查找对应的x坐标 QString fileName = QFileInfo(filePath).fileName(); QString distanceStr = QFileInfo(filePath).dir().dirName(); bool flag; double distance = distanceStr.split("_").first().toDouble(&flag); if (flag) { double xPosition = 0; // 在标定数据中查找对应的x坐标 for (const auto& points : calibrationPoints) { for (const auto& pt : points) { if (qAbs(pt.WorldZ - distance) < 0.1) { xPosition = pt.CameraW + pt.WorldX; break; } } } displayImage(filePath, xPosition); } } } void MainWindow::displayImage(const QString &imagePath, double xPosition) { // 清除现有场景 if (ui->graphicsView->scene()) { delete ui->graphicsView->scene(); } QGraphicsScene *scene = new QGraphicsScene(this); QPixmap pixmap(imagePath); if (!pixmap.isNull()) { // 添加图像到场景 currentPixmapItem = scene->addPixmap(pixmap); scene->setSceneRect(pixmap.rect()); // 添加竖线 if (xPosition > 0) { QPen redPen(Qt::red); redPen.setWidth(2); currentLineItem = scene->addLine(xPosition, 0, xPosition, pixmap.height(), redPen); } else { currentLineItem = nullptr; } ui->graphicsView->setScene(scene); // 初始适应视图 ui->graphicsView->fitInView(scene->sceneRect(), Qt::KeepAspectRatio); currentScale = 1.0; // 启用缩放和平移 ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag); ui->graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); ui->graphicsView->setResizeAnchor(QGraphicsView::AnchorUnderMouse); // 显示图像信息 QString info = QString("图像尺寸: %1 x %2\n文件路径: %3") .arg(pixmap.width()) .arg(pixmap.height()) .arg(imagePath); QGraphicsTextItem *textItem = scene->addText(info); textItem->setPos(10, 10); textItem->setDefaultTextColor(Qt::red); textItem->setZValue(1); // 确保文本显示在最上层 } } // 添加鼠标滚轮事件处理以实现缩放 void MainWindow::wheelEvent(QWheelEvent *event) { if (ui->graphicsView->underMouse()) { double scaleFactor = 1.15; if (event->angleDelta().y() > 0) { // 放大 ui->graphicsView->scale(scaleFactor, scaleFactor); currentScale *= scaleFactor; } else { // 缩小 ui->graphicsView->scale(1.0 / scaleFactor, 1.0 / scaleFactor); currentScale /= scaleFactor; } event->accept(); } else { QMainWindow::wheelEvent(event); } } // 添加鼠标按下事件处理以实现自定义拖拽 void MainWindow::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton && ui->graphicsView->underMouse()) { lastMousePos = event->pos(); setCursor(Qt::ClosedHandCursor); event->accept(); } else { QMainWindow::mousePressEvent(event); } } // 添加鼠标移动事件处理以实现自定义拖拽 void MainWindow::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton && ui->graphicsView->underMouse()) { QPoint delta = event->pos() - lastMousePos; lastMousePos = event->pos(); // 移动视图 QScrollBar *hBar = ui->graphicsView->horizontalScrollBar(); QScrollBar *vBar = ui->graphicsView->verticalScrollBar(); hBar->setValue(hBar->value() - delta.x()); vBar->setValue(vBar->value() - delta.y()); event->accept(); } else { QMainWindow::mouseMoveEvent(event); } } // 添加鼠标释放事件处理 void MainWindow::mouseReleaseEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { setCursor(Qt::ArrowCursor); event->accept(); } else { QMainWindow::mouseReleaseEvent(event); } } // 添加重置视图的槽函数 void MainWindow::onResetView() { if (ui->graphicsView->scene()) { ui->graphicsView->fitInView(ui->graphicsView->scene()->sceneRect(), Qt::KeepAspectRatio); currentScale = 1.0; } } // 添加绘制红线的函数 void MainWindow::drawRedLine(double xPosition) { if (ui->graphicsView->scene() && currentPixmapItem) { // 移除现有的红线 if (currentLineItem) { ui->graphicsView->scene()->removeItem(currentLineItem); delete currentLineItem; } // 创建新红线 QPen redPen(Qt::red); redPen.setWidth(2); QPixmap pixmap = currentPixmapItem->pixmap(); currentLineItem = ui->graphicsView->scene()->addLine( xPosition, 0, xPosition, pixmap.height(), redPen); } } void MainWindow::updateParametersFromUI() { toothParams.CenterDis = ui->centerDisSpinBox->value(); toothParams.SideDis = ui->sideDisSpinBox->value(); toothParams.ToothNum = ui->toothNumSpinBox->value(); toothParams.DeepThresh = ui->deepThreshSpinBox->value(); toothParams.DeepStep = ui->deepStepSpinBox->value(); toothParams.CenterPos = ui->centerPosSpinBox->value(); laserParams.CameraWidth = ui->cameraWidthSpinBox->value(); laserParams.CameraHeight = ui->cameraHeightSpinBox->value(); laserParams.CameraOffsetYCalib = ui->offsetYCalibSpinBox->value(); laserParams.CameraOffsetYMap = ui->offsetYMapSpinBox->value(); laserParams.CameraMapHeight = ui->mapHeightSpinBox->value(); laserParams.RealXOffset = ui->realXOffsetSpinBox->value(); laserParams.RealZOffset = ui->realZOffsetSpinBox->value(); laserParams.CameraPiexSize = ui->pixelSizeSpinBox->value(); laserParams.CameraFocal = ui->focalSpinBox->value(); } void MainWindow::updateUIfromParameters() { ui->centerDisSpinBox->setValue(toothParams.CenterDis); ui->sideDisSpinBox->setValue(toothParams.SideDis); ui->toothNumSpinBox->setValue(toothParams.ToothNum); ui->deepThreshSpinBox->setValue(toothParams.DeepThresh); ui->deepStepSpinBox->setValue(toothParams.DeepStep); ui->centerPosSpinBox->setValue(toothParams.CenterPos); ui->cameraWidthSpinBox->setValue(laserParams.CameraWidth); ui->cameraHeightSpinBox->setValue(laserParams.CameraHeight); ui->offsetYCalibSpinBox->setValue(laserParams.CameraOffsetYCalib); ui->offsetYMapSpinBox->setValue(laserParams.CameraOffsetYMap); ui->mapHeightSpinBox->setValue(laserParams.CameraMapHeight); ui->realXOffsetSpinBox->setValue(laserParams.RealXOffset); ui->realZOffsetSpinBox->setValue(laserParams.RealZOffset); ui->pixelSizeSpinBox->setValue(laserParams.CameraPiexSize); ui->focalSpinBox->setValue(laserParams.CameraFocal); } void MainWindow::on_saveParamsButton_clicked() { QString fileName = QFileDialog::getSaveFileName(this, "保存参数", "", "配置文件 (*.ini)"); if (!fileName.isEmpty()) { QSettings settings(fileName, QSettings::IniFormat); settings.beginGroup("ToothParameters"); settings.setValue("CenterDis", toothParams.CenterDis); settings.setValue("SideDis", toothParams.SideDis); settings.setValue("ToothNum", toothParams.ToothNum); settings.setValue("DeepThresh", toothParams.DeepThresh); settings.setValue("DeepStep", toothParams.DeepStep); settings.setValue("CenterPos", toothParams.CenterPos); settings.endGroup(); settings.beginGroup("LaserParameters"); settings.setValue("CameraWidth", laserParams.CameraWidth); settings.setValue("CameraHeight", laserParams.CameraHeight); settings.setValue("CameraOffsetYCalib", laserParams.CameraOffsetYCalib); settings.setValue("CameraOffsetYMap", laserParams.CameraOffsetYMap); settings.setValue("CameraMapHeight", laserParams.CameraMapHeight); settings.setValue("RealXOffset", laserParams.RealXOffset); settings.setValue("RealZOffset", laserParams.RealZOffset); settings.setValue("CameraPiexSize", laserParams.CameraPiexSize); settings.setValue("CameraFocal", laserParams.CameraFocal); settings.setValue("CameraName", QString(laserParams.CameraName)); settings.endGroup(); } } void MainWindow::on_loadParamsButton_clicked() { QString fileName = QFileDialog::getOpenFileName(this, "加载参数", "", "配置文件 (*.txt)"); if (!fileName.isEmpty()) { QSettings settings(fileName, QSettings::IniFormat); settings.beginGroup("ToothParameters"); toothParams.CenterDis = settings.value("CenterDis", 0).toDouble(); toothParams.SideDis = settings.value("SideDis", 0).toDouble(); toothParams.ToothNum = settings.value("ToothNum", 50).toInt(); toothParams.DeepThresh = settings.value("DeepThresh", 30).toInt(); toothParams.DeepStep = settings.value("DeepStep", 16).toInt(); toothParams.CenterPos = settings.value("CenterPos", 0).toInt(); settings.endGroup(); settings.beginGroup("LaserParameters"); laserParams.CameraWidth = settings.value("CameraWidth", 0).toInt(); laserParams.CameraHeight = settings.value("CameraHeight", 0).toInt(); laserParams.CameraOffsetYCalib = settings.value("CameraOffsetYCalib", 0).toInt(); laserParams.CameraOffsetYMap = settings.value("CameraOffsetYMap", 0).toInt(); laserParams.CameraMapHeight = settings.value("CameraMapHeight", 0).toInt(); laserParams.RealXOffset = settings.value("RealXOffset", 0).toDouble(); laserParams.RealZOffset = settings.value("RealZOffset", 0).toDouble(); laserParams.CameraPiexSize = settings.value("CameraPiexSize", 0).toDouble(); laserParams.CameraFocal = settings.value("CameraFocal", 0).toDouble(); QString cameraName = settings.value("CameraName", "").toString(); strncpy_s(laserParams.CameraName, cameraName.toUtf8().data(), sizeof(laserParams.CameraName)); settings.endGroup(); updateUIfromParameters(); } } 结合我的代码来实现
最新发布
09-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值