FC2カウンター FPGAの部屋 Vivado HLS 2015.4 で OpenCV を使ってみた1

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

FPGAの部屋

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

Vivado HLS 2015.4 で OpenCV を使ってみた1

Vivado HLS 2015.4 で OpenCV を使ってみようということで、やってみた。

参考にするのは、”Vivado Design Suite ユーザー ガイド 高位合成 UG902 (v2015.4) 2015 年 11 月 24 日”の 196 ページの”ビデオ関数”を参照している。
多少古い資料なのだが、XAPP1167 (v1.0) 2013 年 3 月 20 日 ”Vivado HLS ビデオライブラリを使用してZynq で OpenCV アプリケーションを高速化”とその最新英語版、XAPP1167 (v3.0) June 24, 2015 ”Accelerating OpenCV Applications with Zynq-7000 All Programmable SoC using Vivado HLS Video Libraries”も参照している。

取りあえずは、、”Vivado Design Suite ユーザー ガイド 高位合成 UG902 (v2015.4) 2015 年 11 月 24 日”の 198 ページのテストベンチと 199 ページの image_filter() を試してみることにした。

今から使用する Vivado HLSのOpenCV の実装方法は、ハードウエアにする関数の入出力部分はAXI4 Stream で行うということだ。テストベンチでは、IplImage2AXIvideo() で IplImage から AXI4 Stream に直して、image_filter() に入れて、処理後には、AXIvideo2IplImage() で AXI4 Stream から IplImage に戻している。画像処理には、AXI4 Stream を使用するのが、一番自然な流れだと思う。ただ、OpenCV 1.X で書いてあるので、できれば OpenCV 2.X に直したい。
そうそう、テストベンチの方は、"hls_opencv.h" をインクルードする必要があった。その "hls_opencv.h" をVivado HLS のソース表示画面から”CTRL+ クリック”で表示してみると、CvMat2AXIvideo() と AXIvideo2CvMat() があるので、cv::Mat で書けるかもしれない?後でやってみようと思う。

Vivado HLS 2015.4 で opencv_ex_ug プロジェクトを作成した。
テストベンチの opencv_ex_ug_tb.cpp はユーザーズガイドのテストベンチの比較部分を取り除いてある。先ほど書いた、opencv.h をインクルードして、INPUT_IMAGE、OUTPUT_IMAGE、OUTPUT_IMAGE_GOLDEN(これは今のところ使っていないが)を定義した。更に、opencv_ex_ug.h をインクルードしてある。
opencv_ex_ug_tb.cpp を図として下に示す。
Vivado_HLS_OpenCV_1_160401.png

opencv_ex_ug.h を下に示す。
Vivado_HLS_OpenCV_2_160401.png

#ifndef __opencv_ex_ug_H__
#define __opencv_ex_ug_H__

#include "ap_axi_sdata.h"
#include "hls_video.h"

#define MAX_HEIGHT    600
#define MAX_WIDTH    800

typedef hls::stream<ap_axiu<32,1,1,1> > AXI_STREAM;
typedef hls::Scalar<3unsigned char> RGB_PIXEL;
typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> RGB_IMAGE;
#endif


opencv_ex_ug.cpp だが、ユーザーズガイドの 199 ページの image_filter() をほとんどそのまま流用しているが、テストベンチの OpenCV 関数との比較を省いてしまったこともあって、本当にフィルタ結果が正しいのかどうか?確信が持てなかった。そこで、入力した画像をそのまま出力してもらって同じかどうか?を見てみたいと思った。そこで、hls::SubS() のみとした。なお、hls::SubS() は、画像イメージから、スカラー値を引く OpenCV 関数である。マニュアルはXilinx Wiki にある(HLS SubS)。”hls::SubS”で、Xilinx Wiki 上で検索すれば良い。
hls::SubS() では、画像イメージから 0 を引くようにした。つまり、画像イメージのままということになる。
opencv_ex_ug.cpp を下に示す。
Vivado_HLS_OpenCV_3_160401.png

opencv_ex_ug.cpp にAXI4 バス用のディレクティブを追加した。

#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE axis port=OUTPUT_STREAM
#pragma HLS INTERFACE axis port=INPUT_STREAM
#pragma HLS INTERFACE s_axilite port=cols
#pragma HLS INTERFACE s_axilite port=rows


次に、入力画像の”test.bmp”だが、以前から使用している’A’という画像を使用した。
Vivado_HLS_OpenCV_4_160401.png

これで C シミュレーションを行った。結果を示す。比較はしていないので、終了メッセージだけである。
Vivado_HLS_OpenCV_5_160401.png

”test_resullt.bmp”を示す。”test.bmp”と同じだった。
Vivado_HLS_OpenCV_6_160401.png

これで、入出力系は問題ないということが分かった。

これで、C コードを合成してみた。
Vivado_HLS_OpenCV_7_160401.png

AXIvideo2Mat と Mat2AXIvideo が 1 つずつ Verilog HDL ファイルになっていた。
Latency は min が 20 で、max が 1446007 だった。だいぶ離れているが、20 は 0 x 0 の画像の時のレイテンシだろうか?
1446007 は 800 x 600 で割ってみると、3.01 くらいなので、最大の 800 x 600 でフィルタを行った時のレイテンシかな?

リソース使用量を見てみると、画像から 0 を引いているだけので、BRAM_18K は使っていない。
Vivado_HLS_OpenCV_8_160401.png
  1. 2016年04月01日 05:07 |
  2. Vivado HLS
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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