FC2カウンター FPGAの部屋 Vivado HLS を使用した車の白線検出7(Canny フィルタ1)

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

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Vivado HLS を使用した車の白線検出7(Canny フィルタ1)

Vivado HLS を使用した車の白線検出6(hls::HoughLine2() その2)”の続き。

前回、白線検出ハードウェアはとてもZYBO には入らないということがよく分かった。それでも Canny フィルタだけはハードウェアにしたいということでやってみた。

白線検出はグレー変換して、Canny フィルタを掛けているので、Hough 変換とその後の赤いラインを書く部分を削除する。
テストベンチはOpenCV 2.x 形式で書き換えた。

テストベンチの Canny_filter_tb.cpp を示す。

// Canny_fiter_tb.cpp
// 2016/05/20 by marsee
// OpenCV 2 の Mat を使用したバージョン
// 

#include <iostream>
#include "hls_opencv.h"
#include "Canny_filter.h"

using namespace cv;

void canny_filter(AXI_STREAM& input, AXI_STREAM& output, int rows, int cols, int threshold_low, int threshold_high);
void opencv_canny_filter(Mat& src, Mat& dst, int threshold_low, int threshold_high, int sobel_size);

int main (int argc, char** argv) {
    //const int threshold_low = 50;
    //const int threshold_high = 200;
    const int threshold_low = 20;
    const int threshold_high = 30;
    const int sobel_size = 3;

    // OpenCV で 画像を読み込む
    Mat src = imread(INPUT_IMAGE);
    AXI_STREAM src_axi, dst_axi;

    // Mat フォーマットから AXI4 Stream へ変換
    cvMat2AXIvideo(src, src_axi);

    // image_filter() 関数をコール
    canny_filter(src_axi, dst_axi, src.rows, src.cols, threshold_low, threshold_high);

    // AXI4 Stream から Mat フォーマットへ変換
    // dst は宣言時にサイズとカラー・フォーマットを定義する必要がある
    Mat dst(src.rows, src.cols, CV_8UC3);
    AXIvideo2cvMat(dst_axi, dst);

    // Mat フォーマットからファイルに書き込み
    imwrite(OUTPUT_IMAGE, dst);

    // opencv_image_filter() をコール
    Mat dst_cv(src.rows, src.cols, CV_8UC3);
    opencv_canny_filter(src, dst_cv, 50200, sobel_size);
    imwrite(OUTPUT_IMAGE_GOLDEN, dst_cv);

    // dst と dst_cv が同じ画像かどうか?比較する
    for (int y=0; y<src.rows; y++){
        Vec3b* dst_ptr = dst.ptr<Vec3b>(y);
        Vec3b* dst_cv_ptr = dst_cv.ptr<Vec3b>(y);
        for (int x=0; x<src.cols; x++){
            Vec3b dst_bgr = dst_ptr[x];
            Vec3b dst_cv_bgr = dst_cv_ptr[x];

            // bgr のどれかが間違っていたらエラー
            if (dst_bgr[0] != dst_cv_bgr[0] || dst_bgr[1] != dst_cv_bgr[1] || dst_bgr[2] != dst_cv_bgr[2]){
                printf("x = %d, y = %d,  Error dst=%d,%d,%d dst_cv=%d,%d,%d\n", x, y,
                        dst_bgr[0], dst_bgr[1], dst_bgr[0], dst_cv_bgr[0], dst_cv_bgr[1], dst_cv_bgr[2]);
                //return 1;
            }
        }
    }
    printf("Test with 0 errors.\n");

    return 0;
}

void opencv_canny_filter(Mat& src, Mat& dst, int threshold_low, int threshold_high, int sobel_size){
    Canny(src, dst, (double)threshold_low, (double)threshold_high, sobel_size);
}



Canny_fiter プロジェクトを作製した。
Lane-Detecting_36_160521.png

C シミュレーションを行った。パラメータも違うし、値を比較するのが無理のようだ。
Lane-Detecting_37_160521.png

Vivado HLS のHLS ビデオライブラリを使用したCanny フィルタの結果を示す。
Lane-Detecting_38_160522.jpg

OpenCV の Canny フィルタの結果を示す。流石に綺麗だ。
Lane-Detecting_39_160522.jpg

C コードの合成結果を示す。
Lane-Detecting_40_160521.png
Lane-Detecting_41_160521.png

DSP48E のリソース使用量がZYBO のリソース限界を超えている。。。orz

Analysis 表示を示す。
Lane-Detecting_42_160521.png

最初の Filter2D のDSP 使用量が多い。これは、

hls::GaussianBlur<5,5>( src_bw, src_blur, 1.4, 1.4 );

だ。
5x5のガウシアンフィルタなので、大きい様だ。3x3 のガウシアンフィルタにしてみよう。
  1. 2016年05月21日 06:51 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3472-c0821cab
この記事にトラックバックする(FC2ブログユーザー)