Qt 5のOpenCV 4のCanny処理


Cannyエッジ検出アルゴリズムはJohnF.Cannyが1986年に開発したマルチレベルエッジ検出アルゴリズムであり、エッジ検出の最適アルゴリズムとされることも多い.
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html
最適エッジ検出の3つの主な評価基準は:
  • 低エラー率:ノイズによるエラーを最小限に抑えながら、可能な限り多くの実際のエッジを識別します.
  • 高位置決め性:識別されたエッジは、画像内の実際のエッジにできるだけ近づく.
  • 最小応答:画像のエッジは1回しか識別できません.

  • ステップ
    1)ノイズを除去する.ガウス平滑フィルタを使用してノイズを低減します.
    2)勾配幅と方向を計算する.
    2.1一対の畳み込みアレイ(それぞれxy方向に作用)を用いる
    2.2勾配幅値と方向の計算
    3)非極大値抑制.
    4)ヒステリシス閾値.
    uiインタフェースの作成
    Qt5之OpenCV4的Canny处理_第1张图片
    コードの追加
    mainWindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    
    #include "cv2qt.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        void cannyProc(cv::Mat in, int low);
    
    private:
        Ui::MainWindow *ui;
    
        cv::Mat src;
        cv::Mat srcGray;
        cv::Mat dst;
        cv::Mat detected_edges;
    //    int edgeThres = 1;
    //    int lowThreshold;
    //    int max_lowThreshold;
        int ratio = 3;
        int kernel_size = 3;
    
        CV2Qt cv2qt;
    private slots:
        void on_horizontalSlider_valueChanged(int value);
    };
    #endif // MAINWINDOW_H
    

    mainWindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        src = cv::imread("D:/pic/lena.jpg");
        if(src.empty())
            return;
        dst.create(src.size(), src.type());
    
        ui->label->setPixmap(cv2qt.cvMatToQPixmap(src));
        cv::cvtColor(src, srcGray, cv::COLOR_BGR2GRAY);
    
        if(srcGray.empty())
            return;
        ui->horizontalSlider->setValue(20);
        cv::Mat tmp;
    //    cv::threshold(srcGray, tmp, 120., 255., cv::THRESH_BINARY);
        qDebug() << "start canny func";
        cannyProc(srcGray, 20);
        ui->label_2->setPixmap(cv2qt.cvMatToQPixmap(dst));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::cannyProc(cv::Mat in, int low)
    {
        if(in.empty())
            return;
        if(in.channels()>1)
            return;
    //    lowThreshold = low;
        qDebug() << "start blur";
        cv::blur(in, detected_edges, cv::Size(3,3));
        qDebug() << "start canny";
        cv::Canny(detected_edges, detected_edges, low, low*ratio, kernel_size);
        dst= cv::Scalar::all(0);
        qDebug() << "start copy";
        src.copyTo(dst, detected_edges);
    //    out = dst;
    }
    
    void MainWindow::on_horizontalSlider_valueChanged(int value)
    {
        qDebug() << "value: " << value;
        if(srcGray.empty())
            return;
        cv::Mat tmp;
        cannyProc(srcGray, double(value));
        //cv::threshold(srcGray, tmp, double(value), 255., cv::THRESH_BINARY);
        ui->label_2->setPixmap(cv2qt.cvMatToQPixmap(dst));
    }
    
    

    実行結果:
    Qt5之OpenCV4的Canny处理_第2张图片
    ありがとう、親愛なる美しさ.