边缘检测是指找出图像局部强度变化最显著的部分,在目标识别、图像分割提取等领域是非常重要的基础。本文以Canny边缘检测算法为核心,对载入图像进行边缘检测。
文章末尾分享完整源码。开发环境为OpenCV3.4.11+QT5.13+Win10
一、环境搭建QT5与OpenCV环境搭建已经在QT5.13如何配置OpenCV环境这篇有详细的讲解。
二、ui界面规划在Qt Creator新建一个项目,项目新建完成后会默认生成一个空的.ui文件,将界面规划成如下所示:
其中【载入图片】按钮选择原始图片,【显示图片】显示按钮所选的图片,若勾选【灰度图】,则显示灰度图片,【显示】区域显示边缘检测图片,右侧滑动条设置滞后阈值(threshold)。
三、程序编写
编写按钮槽函数
按钮槽函数实现选择图片,并对图片类型进行简单的判断,通过消息框提示错误,选择完成后将图片显示在【显示图片】区。
void MainWindow::on_pushButton_clicked(){ QString FileName = QFileDialog::getOpenFileName(this, tr("文件对话框"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), tr("ALL files (*);;Excel Files(*.jpg)")); if(FileName.contains(".jpg", Qt::CaseSensitive) != true) { qDebug()<<"路径错误!"; QMessageBox::information(nullptr, "错误", "路径错误,\n请重新选择!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); return; } srcImg = imread(FileName.toLocal8Bit().toStdString()); cvtColor(srcImg, grayImg, COLOR_BGR2GRAY); blur(grayImg, grayImg, Size(3,3)); Mat img; if(!isGray) { cvtColor(srcImg, img, CV_BGR2RGB); qtemp = QImage(img.data, img.cols, img.rows, QImage::Format_RGB888); }else{ cvtColor(grayImg, img, CV_GRAY2RGB); qtemp = QImage(img.data, img.cols, img.rows, QImage::Format_RGB888); } QPixmap fiximg = QPixmap::fromImage(qtemp); QPixmap fiximg1 = fiximg.scaled(ui->label->width(), ui->label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); //按比例缩放// QPixmap fiximg1 = fiximg.scaled(ui->label->width(), ui->label->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); //饱满填充 ui->label->setPixmap(fiximg1); ui->label->show();// GaussianBlur(grayImg, grayImg, Size(9, 9), 0, 0); handlefunc(100);}
编写边缘检测函数
使用Canny边缘检测算法对图像进行边缘检测,画出检测轮廓,并将
检测结果显示在【显示】区。
void MainWindow::handlefunc(int thresh){ RNG rng(12345); Mat canny_output; vector> contours; vector hierarchy; // canny 边缘检测 Canny(grayImg, canny_output, thresh, thresh*2, 3); // 寻找轮廓 findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3); // 画出轮廓 for( size_t i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255)); drawContours(drawing, contours, (int) i, color, 2, 8, hierarchy, 0, Point() ); } qtemp = QImage(drawing.data, drawing.cols, drawing.rows, QImage::Format_RGB888); QPixmap fiximg2 = QPixmap::fromImage(qtemp); QPixmap fiximg3 = fiximg2.scaled(ui->labelShow->width(), ui->labelShow->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); //按比例缩放// QPixmap fiximg1 = fiximg.scaled(ui->labelShow->width(), ui->labelShow->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); //饱满填充 ui->labelShow->setPixmap(fiximg3); ui->labelShow->show();}
滑动条设置滞后阈值
滑动条修改滞后阈值,观察边缘检测效果。void MainWindow::on_verticalSlider_sliderMoved(int position){ qDebug()< handlefunc(position);}