图像的ROI(region of interest)是指图像中感兴趣区域。在OpenCV中图像设置图像ROI区域,实现只对ROI区域操作。
前言
越来越多的开发人员选择基于开源的Qt框架与OpenCV来实现界面和算法,其原因不单单是无版权问题,更多是两个社区的发展蓬勃,可用来学习的资料与例程特别丰富。以下是关于利用Qt的rubberBand和OpenCV进行图像的ROI区域获取
软件版本:Qt-5.12.0/OpenCV-4.5.3
平台:Windows10/11–64
一、GUI
二、实现代码
1、Rubber
void MainWindow::on_graphicsView_1_rubberBandChanged(const QRect &viewportRect, const QPointF &fromScenePoint, const QPointF &toScenePoint) { rubberFunc(viewportRect, fromScenePoint, toScenePoint); } void MainWindow::rubberFunc(const QRect &viewportRect, const QPointF &fromScenePoint, const QPointF &toScenePoint) { size_t numView = ui->tabWidget->currentIndex() % 3; QPoint topLeft = viewportRect.topLeft(); int x1 = topLeft.x(); double xFromScene = fromScenePoint.x(); double yFromScene = fromScenePoint.y(); double xToScene = toScenePoint.x(); double yToScene = toScenePoint.y(); if (x1 != 0) { ui->rubberX1Spin->setValue(static_cast<int>(xFromScene)); ui->rubberY1Spin->setValue(static_cast<int>(yFromScene)); ui->rubberX2Spin->setValue(static_cast<int>(xToScene)); ui->rubberY2Spin->setValue(static_cast<int>(yToScene)); *tmpMat = dispMat[numView]->clone(); cv::rectangle(*tmpMat, cv::Point(static_cast<int>(xFromScene), static_cast<int>(yFromScene)), \ cv::Point(static_cast<int>(xToScene), \ static_cast<int>(yToScene)), \ cv::Scalar(0, 0, 255), 1, 1, 0); } if (tmpMat->channels() == 3) { QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \ static_cast<int>(tmpMat->step), \ QImage::Format_RGB888); dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped())); } else { QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \ static_cast<int>(tmpMat->step), \ QImage::Format_Grayscale8); dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped())); } }
2、ROI
void MainWindow::on_maskBtn_clicked() { size_t numView = ui->tabWidget->currentIndex() % 3; int x1 = ui->roiX1Spin->value(); int y1 = ui->roiY1Spin->value(); int x2 = ui->roiX2Spin->value(); int y2 = ui->roiY2Spin->value(); if ((x1 == 0)&&(y1 == 0)&&(x2 == 0)&&(y2 == 0)) { outputInfo(2, tr("Please check the Points.")); return; } cv::Rect maskRect(x1, y1, x2 - x1, y2 - y1); cv::Mat maskMat = cv::Mat::zeros(dispMat[numView]->size(), \ CV_8UC1); tmpMat->zeros(dispMat[numView]->size(), \ dispMat[numView]->type()); maskMat(maskRect).setTo(255); dispMat[numView]->copyTo(*tmpMat, maskMat); if (ui->roiChkBox->isChecked()) { *dispMat[numView] = tmpMat->clone(); cvtMatPixmap(dispMat, dispPixmap, numView); } else { if (tmpMat->channels() == 3) { QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \ static_cast<int>(tmpMat->step), \ QImage::Format_RGB888); dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped())); } else { QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \ static_cast<int>(tmpMat->step), \ QImage::Format_Grayscale8); dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped())); } } outputInfo(1, tr("Mask done.")); } void MainWindow::on_roiBtn_clicked() { size_t numView = ui->tabWidget->currentIndex() % 3; int x1 = ui->roiX1Spin->value(); int y1 = ui->roiY1Spin->value(); int x2 = ui->roiX2Spin->value(); int y2 = ui->roiY2Spin->value(); if ((x1 == 0)&&(y1 == 0)&&(x2 == 0)&&(y2 == 0)) { outputInfo(2, tr("Please check the Points.")); return; } cv::Rect maskRect(x1, y1, x2 - x1, y2 - y1); cv::Mat roiMat = (*dispMat[numView])(maskRect); *tmpMat = roiMat.clone(); if (ui->roiChkBox->isChecked()) { *dispMat[numView] = tmpMat->clone(); cvtMatPixmap(dispMat, dispPixmap, numView); } else { if (tmpMat->channels() == 3) { QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \ static_cast<int>(tmpMat->step), \ QImage::Format_RGB888); dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped())); } else { QImage tmpImage = QImage(tmpMat->data, tmpMat->cols,tmpMat->rows, \ static_cast<int>(tmpMat->step), \ QImage::Format_Grayscale8); dispPixmap[numView]->setPixmap(QPixmap::fromImage(tmpImage.rgbSwapped())); } } outputInfo(1, tr("roiMat done.")); }
总结
以上是关于利用Qt进行GUI构建并使用rubberBandChanged进行roi区域获取,或者直接使用OpenCV的roiMat()进行感兴趣区域获取。