Qt OpenCV画像処理　測長 -画像特定箇所判定

◆プログラムの目的：画像から一部のみを取得し、測長する。

◆処理手順概要：
画像取得→2値化→輪郭抽出→ある一定の太さのものだけ測長（太いもの、細いもの)

※作成中のため, imshowにて表示　今後修整予定

◆環境
windows10
visualStudio community 2015
Qt5.7
C++
openCV3.4.6 (openCV4は対応していない）

◆ソースコード
※main.cpp はデフォルトのまま
※MainWindow.cpp はデフォルトのまま（まだ作成していないので imshowと空白のGUI表示になる）
-------------------------------------------------

◆test_openCV_measure.pro

```
#-------------------------------------------------
#
# Project created by QtCreator 2019-05-25T16:17:48
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = test_openCV_measure
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

win32:DEPENDPATH  += "C:\opencv\build\include"
win32:INCLUDEPATH += "C:\opencv\build\include"
//win32:LIBS += -L"C:\opencv\build\x64\vc14\lib"
win32:LIBS += -L"C:\opencv\build\x64\vc15\lib"
//win32:LIBS += -lopencv_core245 -lopencv_highgui245 -lopencv_imgproc245
win32:LIBS += -lopencv_world346
```

-------------------------------------------------
◆mainwindow.h

```
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

```

-------------------------------------------------
◆mainwindow.cpp

```
//流用元：https://cvtech.cc/measure
//openCV 3.4.6 使用 //openCV4はNG:関数返り値など違うため
//
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "opencv2/world.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <QDebug>

using namespace cv;
using namespace std; //追加  https://cvtech.cc/measure/3/

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //画像の表示と2値化(白黒)　https://cvtech.cc/measure/2
    //Mat img = imread("root.jpg", IMREAD_UNCHANGED);
    Mat img = imread("C:/work/qt/test_openCV_measure/root.jpg", IMREAD_UNCHANGED);
    Mat gray_img;
    //cvtColor(img, gray_img, CV_BGR2GRAY);
    cv::cvtColor(img, gray_img, COLOR_BGR2GRAY); //画像の2値化(白黒)
    Mat bin_img;
    threshold(gray_img, bin_img, 0, 255, THRESH_BINARY|THRESH_OTSU);
    bin_img = ~bin_img;
    Mat bin_img_copy=bin_img.clone(); //追加 https://cvtech.cc/measure/4
    Mat element = Mat::ones(9,9,CV_8UC1); //追加 //追加 https://cvtech.cc/measure/4
    //imshow("IMAGE",bin_img); //2値化(白黒)された画像の表示
    //waitKey(10000);
    //画像の表示　https://cvtech.cc/measure/2

    //findContours関数で輪郭を検出する 追加ここから https://cvtech.cc/measure/3/
    vector<vector<Point> > contours;
    //findContours(bin_img, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    //findContours 必ずopenCV3 を使うことopenCV4 では 関数返り値が違うために、正常に動作しないなどがある
    //参考:http://opencv.jp/opencv-2svn/cpp/structural_analysis_and_shape_descriptors.html
    //CV_RETR_LIST すべての輪郭を抽出しますが，一切の階層構造を保持しません
    //CV_CHAIN_APPROX_NONE すべての輪郭点を完全に格納します．つまり，この手法により格納された任意の隣り合う2点は，互いに8近傍に存在します．
    cv::findContours(bin_img, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    double contour_len=0;
    for(int i = 0; i < contours.size(); ++i) {
        contour_len += arcLength(contours.at(i),1);
    }
    //cout<<"estimated root length = "<<contour_len/2<<endl;
    qDebug() <<"estimated root length = "<< QString::number((contour_len)/2)<<endl; //測長結果表示
    //imshow("IMAGE",bin_img); //画像全体の輪郭イメージ表示
    //waitKey(10000); //入力を待つ
    //追加ここまで https://cvtech.cc/measure/3/

    //追加ここから　https://cvtech.cc/measure/4/
    //erode(bin_img_copy, bin_img_copy, element, Point(-1,-1), 1);
    cv::erode(bin_img_copy, bin_img_copy, element, Point(-1,-1), 1);
    imshow("IMAGE_main_root",bin_img_copy);
    vector<vector<Point> > contours_main;
    //findContours(bin_img_copy, contours_main, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    cv::findContours(bin_img_copy, contours_main, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    double contour_len_main=0;
    for(int i = 0; i < contours_main.size(); ++i) {
        contour_len_main += arcLength(contours_main.at(i),0);
    }
    //cout<<"estimated root length (main) = "<<contour_len_main/2<<endl;
    //cout<<"estimated root length (lateral) = "<<(contour_len-contour_len_main)/2<<endl;
    //画像一部を取り出して、測長結果を表示する
    qDebug() <<"estimated root length (main) = "<< QString::number(contour_len_main/2)<<endl;
    //画像一部を取り出して、測長結果を表示する
    qDebug() <<"estimated root length (lateral) = "<<QString::number((contour_len-contour_len_main)/2 )<<endl;
    //追加ここまで https://cvtech.cc/measure/4/

    return;

}

MainWindow::~MainWindow()
{
    delete ui;
}
```

-------------------------------------------------

◆mainwindow.cpp

```


```