FPGAの部屋

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。ご利用ください。 http://marsee101.web.fc2.com/index.html

2016年05月

ZYBO 上のOpenCV で白線検出2(equalizeHist() を使用した場合2)”の続き。

今回は前回のコードはそのままに、10行目の”#define HIST”をコメントアウトして、equalizeHist() を使用しないで、Canny フィルタのみで白線検出を行うことにする。なお、Canny フィルタのスレッショルドは、試行錯誤して、最適化したつもりだ。

最初に、test_1080p.bmp からやってみた。
34aa048c.png


白線検出の経過時間は 0.221 sec 程度だった。前回よりも 0.057 sec 速かった。
白線検出結果を示す。
7f29ac80.jpg


白線検出ができてる。なお、source ウインドウは今回はカラーで取り込んでいる。

次に road_1.jpg の結果を示す。
6013498a.png


白線検出の経過時間は 0.416 sec 程度だった。前回は、source ウインドウは白黒だが、0.638 sec 程度だった。
白線検出結果を示す。
8ebcb393.jpg


次に road_2.jpg の結果を示す。
1ee53f61.png


白線検出の経過時間は 0.414 sec 程度だった。前回は、source ウインドウは白黒だが、1.290 sec 程度だった。大幅に速くなっている。これだったら使えそうだ。1秒回に 2 回は判定できる。
白線検出結果を示す。
72982de9.jpg


次に road_3.jpg の結果を示す。
091f5fcc.png


白線検出の経過時間は 0.394 sec 程度だった。前回は、source ウインドウは白黒だが、1.300 sec 程度だった。こちらも大幅に速くなっている。
白線検出結果を示す。
0e70f384.jpg


最後に、road_4.jpg の結果を示す。
286722ab.png


白線検出の経過時間は 0.320 sec 程度だった。前回は、source ウインドウは白黒だが、0.604 sec 程度だった。
白線検出結果を示す。
d307dcf0.jpg


全体に白線検出の速度は上がっている。equalizeHist() を外したおかげもあるが、HoughLines() で検出する直線の数が経過時間に影響するようだ。

2016年5月27日(金)にパソコンをWindows 7 からWindows10にアップグレードしました。
ほかのパソコンをWindows10にアップグレードして、FPGAの環境に影響しないことを確認したので、無料アップグレード期間が終了する前にアップグレードしました。

最新のVivado 2016.1はWindows 10 対応で問題ないです。ISE は”Windows8以降のOSでISE WebPACKを動かす”を参考にさせていただいて、DLLを取り換えると動作に問題ないようです。

Xming なども問題なく動作して、今のところ、不具合はないですね。

Z-turn Board が昨日届きました。注文してから足掛け3日で届きました。

箱の中には、Z-turn BoardZ-turn IO Cape とデータが入ったDVDが入っていました。
06fefd51.jpg


袋を開けるとZ-turn Board には、Micro SDカードが入っていました。
f7f65ef5.jpg


Z-turn IO Cape のコネクタにZ-turn Board を挿入しました。
16a32c34.jpg


これでPmod やIOピンが使いやすくなりました。上の写真ではZYNQ の型番も見えます。 XC7Z020CLG400-1C です。

DVD の中身です。マニュアルやツール、ソースなどが入っています。
5a484cff.png

”ZYBO 上のOpenCV で白線検出1(equalizeHist() を使用した場合)”の続き。

前回は、equalizeHist() を使用し、Canny フィルタを掛けて、HoughLine 変換で道路の白線検出を行った。しかし、画像を読み込む時点で白黒画像に変換していた。ハードウェアでは、カメラで撮影した画像を白黒変換して、Canny フィルタを掛ける予定なので、白黒画像変換の部分の経過時間も測る必要がある。それでC++ ソースコードを修正した。更に、白黒画像変換+Canny フィルタの経過時間を測定した。

Hough_example.cpp を下に示す。

// Line Detection by Hough Line Transform
// http://opencvexamples.blogspot.com/2013/10/line-detection-by-hough-line-transform.html

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <sys/time.h>

#define HIST

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
    Mat src;
    
    if (argc >= 1){
        src = imread(argv[1]);
    } else {
        printf("Usage : HoughLine_example <read_file_name>\n");
        exit(1);
    }

    Mat dst, cdst;
    Mat src_g;
    struct timeval start_time, end_time;

    gettimeofday(&start_time, NULL);

    cvtColor(src, src_g, CV_BGR2GRAY);
#ifdef HIST
    Mat eqst;
    equalizeHist(src_g, eqst);
    Canny(eqst, dst, 1502503); // for equalizeHist
#else
    //Canny(src_g, dst, 50, 200, 3); // Normal
    Canny(src_g, dst, 2003003); // Normal2
#endif

    //gettimeofday(&end_time, NULL);
    
    cvtColor(dst, cdst, CV_GRAY2BGR);

    vector<Vec2f> lines;
    // detect lines
    HoughLines(dst, lines, 1, CV_PI/18015000);

    gettimeofday(&end_time, NULL);
    
    // draw lines
    for( size_t i = 0; i < lines.size(); i++ )
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
    }
    
    if (end_time.tv_usec < start_time.tv_usec) {
        printf("total time = %ld.%06ld sec\n", end_time.tv_sec - start_time.tv_sec - 11000000 + end_time.tv_usec - start_time.tv_usec);
    }
    else {
        printf("total time = %ld.%06ld sec\n", end_time.tv_sec - start_time.tv_sec, end_time.tv_usec - start_time.tv_usec);
    }

#ifdef HIST
    imshow("equalizeHist", eqst);
#endif
    imshow("Canny", dst);
    imshow("source", src);
    imshow("detected lines", cdst);

    waitKey();
    waitKey();
    waitKey();
    waitKey();
    
    return 0;
}


./Hough_example test_1080p.bmp コマンドを実行した。
43fd7bc1.png


白線検出の経過時間は 0.278 sec 程度だった。前回は 0.273 sec だったので、約 5 ms 程度、白黒変換にかかることが分かった。

白線検出結果を示す。結果は前回と同じだが、source ウインドウがカラーなのが分かる。
90fe85d8.jpg


次に、白黒画像変換+Canny フィルタの経過時間を測定する。
現在の”gettimeofday(&end_time, NULL);”の行をコメントアウトして、現在コメントになっている同様の行のコメントを外した。もう一度コンパイルして、やってみた。

すると、白黒画像変換+Canny フィルタの経過時間は、57 ms くらいのようだ。
d4ed0714.png

Vivado HLS を使用した車の白線検出9(Canny フィルタ3)”で、大体Vivado HLS による C シミュレーションでは白線検出が出来てきたと思うので、本命のZYBO のOpenCV 環境でまずはソフトウェアで、どのくらいの速度で白線検出をできるかどうかをテストしてみた。

ZYBO のUbuntu 14.04 LTS 上のOpenCV 2.4.10 で白線検出のテストを行った。
白線検出用のアプリケーションの HoughLine_example.cpp を示す。最初は、equalizeHist() を行う設定でやってみた。
49a28f7e.png

// Line Detection by Hough Line Transform
// http://opencvexamples.blogspot.com/2013/10/line-detection-by-hough-line-transform.html

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <sys/time.h>

#define HIST

using namespace cv;
using namespace std;

int main(int argc, char *argv[])
{
    Mat src;
    
    if (argc >= 1){
        src = imread(argv[1], 0);
    } else {
        printf("Usage : HoughLine_example <read_file_name>\n");
        exit(1);
    }

    Mat dst, cdst;
    struct timeval start_time, end_time;

    gettimeofday(&start_time, NULL);

#ifdef HIST
    Mat eqst;
    equalizeHist(src, eqst);
    Canny(eqst, dst, 1502503); // for equalizeHist
#else
    Canny(src, dst, 502003); // Normal
    //Canny(src, dst, 200, 300, 3); // Normal2
#endif

    cvtColor(dst, cdst, CV_GRAY2BGR);

    vector<Vec2f> lines;
    // detect lines
    HoughLines(dst, lines, 1, CV_PI/18015000);

    gettimeofday(&end_time, NULL);
    
    // draw lines
    for( size_t i = 0; i < lines.size(); i++ )
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
    }
    
    if (end_time.tv_usec < start_time.tv_usec) {
        printf("total time = %ld.%06ld sec\n", end_time.tv_sec - start_time.tv_sec - 11000000 + end_time.tv_usec - start_time.tv_usec);
    }
    else {
        printf("total time = %ld.%06ld sec\n", end_time.tv_sec - start_time.tv_sec, end_time.tv_usec - start_time.tv_usec);
    }

#ifdef HIST
    imshow("equalizeHist", eqst);
#endif
    imshow("Canny", dst);
    imshow("source", src);
    imshow("detected lines", cdst);

    waitKey();
    waitKey();
    waitKey();
    waitKey();
    waitKey();
    
    return 0;
}


このアプリケーションを使用して、最初に test_1080p.bmp の白線検出をやってみた。
7b3fbe1d.png


白線検出の経過時間は0.273 sec 位だった。下に白線検出の結果を示す。
4d6ca20f.jpg


良さそうだ。

次に、自分で撮影した4つの写真の白線検出結果を見た。

まずは、 road_1.jpg の白線検出を行った。
0823dd0c.png


白線検出の経過時間は0.638 sec 位だった。下に白線検出の結果を示す。
333e3b24.jpg


良さそうではあるが、電線の影を検出している。

次に、road_2.jpg の白線検出を行った。
5fdb9df6.png


白線検出の経過時間は1.290 sec 位だった。下に白線検出の結果を示す。
74e2ccec.jpg


road_1.jpg の方が逆光で、road_2.jpg の方が順光だからか?道路のちょっとした凸凹までエッジとして検出されているので、Hough変換で相当な量の直線を検出したようだ。

road_3.jpg の白線検出を行った。road_3.jpg は road_2.jpg の反対のレーンから撮影した写真なので、road_2.jpg の結果と同じような傾向になるはずだ。
25f50bbe.png
 

白線検出の経過時間は 1.300 sec 程度だった。下に白線検出結果を示す。
bfdaebcd.jpg


やはり、 road_2.jpg と同様の結果になった。

最後に、road_4.jpg の白線検出を行った。同様に、road_4.jpg は road_1.jpg と同様の写真である。
135582bd.png


白線検出の経過時間は、0.604 程度だった。下に白線検出結果を示す。
352465f7.jpg


road_2.jpg と road_3.jpg の白線検出が酷い気がする。equalizeHist() を使用すると、現在のパラメータでは、このカメラの順光時のアスファルト舗装の細かい凸凹がよく見えるようになってしまう。

どうやら、Hough 変換の実行時間は検出した本数が多いほど、遅くなっているのでは?と思う。

↑このページのトップヘ