qt c++有没有办法通过鼠标左键在qgraphicsview上将opencv的findContours函数处理后的coutours点位图进行编辑,例如擦除原有部分区域和增加选取新的roi区域
时间: 2024-04-04 11:35:29 浏览: 110
可以通过继承QGraphicsView来实现您的需求。您需要重载QGraphicsView的mousePressEvent、mouseMoveEvent和mouseReleaseEvent三个函数来响应鼠标事件。
在mousePressEvent中获取当前鼠标点击的坐标,并将其转换为图像坐标系中的坐标。然后使用OpenCV的pointPolygonTest函数判断该点是否在某个contour中。如果是,则记录该contour的索引,表示用户想要对该contour进行编辑。
在mouseMoveEvent中,根据用户操作的类型(如擦除或增加),修改对应的contour的点集。可以使用OpenCV的drawContours函数将修改后的contour绘制到一张Mat中。
在mouseReleaseEvent中,将修改后的Mat重新显示到QGraphicsView中。
下面是一段示例代码,可以实现在QGraphicsView上对contour进行编辑:
```c++
class MyGraphicsView : public QGraphicsView {
public:
MyGraphicsView(QWidget* parent = nullptr)
: QGraphicsView(parent) {
setDragMode(QGraphicsView::ScrollHandDrag);
setRenderHint(QPainter::Antialiasing);
setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, true);
}
protected:
void mousePressEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
QPoint pos = event->pos();
QPointF scenePos = mapToScene(pos);
cv::Point2f pt(scenePos.x(), scenePos.y());
int idx = -1;
for (int i = 0; i < contours.size(); ++i) {
double dist = cv::pointPolygonTest(contours[i], pt, false);
if (dist >= 0) {
idx = i;
break;
}
}
selectedContour = idx;
}
}
void mouseMoveEvent(QMouseEvent* event) override {
if (selectedContour < 0) {
QGraphicsView::mouseMoveEvent(event);
return;
}
QPoint pos = event->pos();
QPointF scenePos = mapToScene(pos);
cv::Point2f pt(scenePos.x(), scenePos.y());
if (event->modifiers() & Qt::ShiftModifier) {
// 擦除contour中包含该点的部分
for (auto& p : contours[selectedContour]) {
double dist = cv::norm(p - pt);
if (dist < 10) {
p.x = -1;
p.y = -1;
}
}
} else {
// 增加新的contour点
contours[selectedContour].push_back(cv::Point2f(scenePos.x(), scenePos.y()));
}
// 绘制contours
cv::Mat mat(image.size(), CV_8UC3, cv::Scalar(255, 255, 255));
cv::drawContours(mat, contours, selectedContour, cv::Scalar(0, 0, 255), cv::FILLED);
cv::drawContours(mat, contours, -1, cv::Scalar(0, 255, 0), 1);
QImage qimg(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
QGraphicsPixmapItem* pixmapItem = new QGraphicsPixmapItem(QPixmap::fromImage(qimg));
scene()->addItem(pixmapItem);
}
void mouseReleaseEvent(QMouseEvent* event) override {
if (selectedContour < 0) {
QGraphicsView::mouseReleaseEvent(event);
return;
}
// 更新contours
std::vector<cv::Point2f> newContour;
for (auto& p : contours[selectedContour]) {
if (p.x >= 0 && p.y >= 0) {
newContour.push_back(p);
}
}
contours[selectedContour] = newContour;
selectedContour = -1;
// 绘制contours
cv::Mat mat(image.size(), CV_8UC3, cv::Scalar(255, 255, 255));
cv::drawContours(mat, contours, -1, cv::Scalar(0, 255, 0), 1);
QImage qimg(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
QGraphicsPixmapItem* pixmapItem = new QGraphicsPixmapItem(QPixmap::fromImage(qimg));
scene()->addItem(pixmapItem);
}
private:
cv::Mat image; // 原始图像
std::vector<std::vector<cv::Point2f>> contours; // 处理后的contours点集
int selectedContour = -1; // 当前选中的contour索引
};
```
阅读全文