FC2カウンター FPGAの部屋 Vitis HLS 2021.2 で Vitis Vision Library を使用する5(AXI4-Stream 入出力の xf_median_blur 編 1)
fc2ブログ

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

FPGAの部屋

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

Vitis HLS 2021.2 で Vitis Vision Library を使用する5(AXI4-Stream 入出力の xf_median_blur 編 1)

Vitis HLS 2021.2 で Vitis Vision Library を使用する4(rgbirbayer 編)”の続き。

Vitis HLS 2021.2 で dilation を実装してみることにしたということで、前回は、rgbirbayer をやってみた。これは、AXI4-Stream 入出力で実装されている。dilation 編同様、Vitis HLS 2020.2 でプロジェクトを作成してから Vitis HLS 2021.2 で C コードの合成をやってみた。なお、入力画像が用意できないので、シミュレーションは無しとする。結果は Vitis HLS 2020.2 では C コードの合成が成功したが、Vitis HLS 2021.2 ではエラーになってしまった。今回は、本命の AXI4-Stream 入出力のメディアン・フィルタをやってみよう。

以前、xfOpenCV で AXI4-Stream 版の medianblur をやってみた。”Vivado HLS 2019.2 で xfOpenCV のAXI4-Stream 版 medianblur をやってみる1
Vitis HLS 2020.2 のときに、この xfOpenCV 版をやってみたが、エラーで合成ができなかった。”Vitis Vision Library で AXI4-Stream 入出力の medianblur を実装する1
今回、AXI4-Stream 入出力のサンプルコードの rgbirbayer が公開されていたので、それに合わせて”Vivado HLS 2019.2 で xfOpenCV のAXI4-Stream 版 medianblur をやってみる1”を変更した。
プロジェクトは Vitis HLS 2020.2 で作成し、そのプロジェクトを Vitis HLS 2021.2 で使用することにする。

xf_median_blur.h を示す。

// xf_median_blur.h
// 2020/03/09 by marsee
// xfopencv/examples/medianblur/xf_median_blur_config.h のコードを引用している
// https://github.com/Xilinx/xfopencv/blob/master/examples/medianblur/xf_median_blur_config.h
// xfopencv/examples/medianblur/xf_config_params.h のコードを引用している
// https://github.com/Xilinx/xfopencv/blob/master/examples/medianblur/xf_config_params.h
// 2022/01/10 : for Vitis Vision Library

#ifndef __XF_MEDIAN_BLUR_H__
#define __XF_MEDIAN_BLUR_H__

#include "hls_stream.h"
#include "ap_int.h"
#include "common/xf_common.hpp"
#include "ap_axi_sdata.h"
#include "common/xf_infra.hpp"
#include "common/xf_axi_io.hpp"

#include "imgproc/xf_median_blur.hpp"
//#include "xf_config_params.hpp"

#define NO  1  // Normal Operation
#define RO  0  // Resource Optimized

#define RGB 1
#define GRAY 0

/* Filter window size*/
#define WINDOW_SIZE 3

/*  set the height and weight  */
#define WIDTH  1920
#define HEIGHT 1080

#if NO
#define NPxPC XF_NPPC1
#else
#define NPxPC XF_NPPC8
#endif

#if GRAY
#define TYPE XF_8UC1
#define CHANNELS 1
#define STREAMW 8
#else
#define TYPE XF_8UC3
#define CHANNELS 3
#define STREAMW 32
#endif

typedef hls::stream<ap_axiu<STREAMW,1,1,1> > AXI_STREAM;

#endif


xf_median_blur.cpp を示す。

// xf_median_blur.cpp
// 2020/03/08 by marsee

// xfopencv/HLS_Use_Model/Standalone_HLS_AXI_Example/xf_ip_accel_app.cpp のコードを引用している
// https://github.com/Xilinx/xfopencv/blob/master/HLS_Use_Model/Standalone_HLS_AXI_Example/xf_ip_accel_app.cpp
// xfopencv/examples/medianblur/xf_median_blur_accel.cpp のコードを引用している
// https://github.com/Xilinx/xfopencv/blob/master/examples/medianblur/xf_median_blur_accel.cpp
// 2022/01/10 : for Vitis Vision Library

#include "xf_median_blur.h"

void median_blur_accel_axis(AXI_STREAM& _src, AXI_STREAM& _dst, int img_height, int img_width){
#pragma HLS INTERFACE mode=s_axilite port=img_width
#pragma HLS INTERFACE mode=s_axilite port=img_height
#pragma HLS INTERFACE mode=s_axilite port=return
#pragma HLS INTERFACE mode=axis register_mode=both port=_src register
#pragma HLS INTERFACE mode=axis register_mode=both port=_dst register

    xf::cv::Mat<TYPE, HEIGHT, WIDTH, NPxPC> img_in(img_height, img_width);
    xf::cv::Mat<TYPE, HEIGHT, WIDTH, NPxPC> img_out(img_height, img_width);

#pragma HLS DATAFLOW

    xf::cv::AXIvideo2xfMat(_src, img_in);

    xf::cv::medianBlur <WINDOW_SIZE, XF_BORDER_REPLICATE, TYPE, HEIGHT, WIDTH,  NPxPC> (img_in, img_out);

    xf::cv::xfMat2AXIvideo(img_out, _dst);
}


xf_median_blur_tb.cpp を示す。

// xf_median_blur_config_tb.cpp
// 2020/03/08 by marsee

// xfopencv/HLS_Use_Model/Standalone_HLS_AXI_Example/xf_dilation_tb.cpp のコードを引用している
// https://github.com/Xilinx/xfopencv/blob/master/HLS_Use_Model/Standalone_HLS_AXI_Example/xf_dilation_tb.cpp
// xfopencv/examples/medianblur/xf_median_blur_tb.cpp のコードを引用している
// https://github.com/Xilinx/xfopencv/blob/master/examples/medianblur/xf_median_blur_tb.cpp
// 2022/01/10 : for Vitis Vision Library

#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "xf_median_blur.h"
#include "common/xf_axi.hpp"
#include "common/xf_sw_utils.hpp"

void median_blur_accel_axis(AXI_STREAM& _src, AXI_STREAM& _dst, int img_height, int img_width);

int main(int argc, char** argv)
{

    if(argc != 2)
    {
        fprintf(stderr,"Invalid Number of Arguments!\nUsage:\n");
        fprintf(stderr,"<Executable Name> <input image path> \n");
        return -1;
    }

    cv::Mat out_img,ocv_ref;
    cv::Mat in_img,in_img1,diff;

    // reading in the color image
#if GRAY
    in_img = cv::imread(argv[1], 0);
#else
    in_img = cv::imread(argv[1], 1);
#endif
    if (in_img.data == NULL)
    {
        fprintf(stderr,"Cannot open image at %s\n", argv[1]);
        return 0;
    }
    // create memory for output images
    /*  reading the gray/color image  */
#if GRAY
    ocv_ref.create(in_img.rows,in_img.cols,CV_8UC1);
    out_img.create(in_img.rows,in_img.cols,CV_8UC1);
    diff.create(in_img.rows,in_img.cols,CV_8UC1);
    in_img1.create(in_img.rows,in_img.cols,CV_8UC1);

#else
    ocv_ref.create(in_img.rows,in_img.cols,CV_8UC3);
    out_img.create(in_img.rows,in_img.cols,CV_8UC3);
    diff.create(in_img.rows,in_img.cols,CV_8UC3);
    in_img1.create(in_img.rows,in_img.cols,CV_8UC3);
#endif
    int img_height = in_img.rows;
    int img_width = in_img.cols;

    /////////////////   Opencv  Reference  ////////////////////////
    cv::medianBlur(in_img,ocv_ref,WINDOW_SIZE);
    cv::imwrite("out_ocv.jpg", ocv_ref);

    AXI_STREAM _src,_dst;

    xf::cv::cvMat2AXIvideoxf<NPxPC>(in_img, _src);
    median_blur_accel_axis(_src, _dst, img_height, img_width);
    xf::cv::AXIvideo2cvMatxf<NPxPC>(_dst, in_img1);

    cv::imwrite("hls.jpg", in_img1);
    //////////////////  Compute Absolute Difference ////////////////////

    cv::absdiff(ocv_ref, in_img1, diff);

    float err_per;
    xf::cv::analyzeDiff(diff,0,err_per);
    cv::imwrite("diff_img.jpg",diff);

    in_img.~Mat();
    out_img.~Mat();
    ocv_ref.~Mat();
    in_img.~Mat();
    in_img1.~Mat();
    diff.~Mat();

    if(err_per > 0.0f)
    {
        return 1;
    }

    return 0;
}



Vitis HLS 2020.2 で xf_median_blur プロジェクトを作成した。
Vitis_Vision2_38_220116.png

xf_median_blur ディレクトリに 1280 x 720 ピクセルの test2.jpg 、 xf_median_blur.h, xf_median_blur.cpp, xf_median_blur_tb.cpp をコピーした。
Vitis_Vision2_39_220116.png

test2.jpg を示す。ランダム・ノイズを画像に重畳している。
Vitis_Vision2_45_220116.jpg

Vitis HLS 2021.2 の Project メニューから Project Settings... を選択して、設定を行う。
Project Settings (xf_median_blur) ダイアログが開く。
左のウインドウで Simulation をクリックする。
xf_median_blur_tb.cpp の CFLAGS を設定する。(設定方法は、Edit CFLAGS... ボタンをクリックする)
xf_median_blur_tb.cpp の CFLAGS に

-I/media/masaaki/Ubuntu_Disk/Xilinx_github/Vitis_Libraries/vision/L1/include -std=c++0x -I/usr/local/include

を設定した。

Linker Flags に

-L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_imgproc

を設定した。
Input Arguments に

/media/masaaki/Ubuntu_Disk/Vitis_HLS/ZYBO_Z7_20/2021.2/xf_median_blur/test2.jpg

を設定した。
Vitis_Vision2_41_220116.png

Project Settings (xf_median_blur) ダイアログの左のウインドウで Synthesis をクリックしxf_median_blur.cpp の CFLAGS を設定する。(設定方法は、Edit CFLAGS... ボタンをクリックする)

-I/media/masaaki/Ubuntu_Disk/Xilinx_github/Vitis_Libraries/vision/L1/include -std=c++0x

を設定した。
Vitis_Vision2_41_220116.png

ZYBO Z7-20 を使用するので、64 ビットアドレスの DMA を禁止して、 32 ビットアドレスの DMA にする。
Vitis HLS の Solution メニューから Solution Settings... を選択する。
Solution Settings (solution1) ダイアログが開く。
config_interface を展開して、m_axi_addr64 の Value のチェックボックスのチェックを外した。
Vitis_Vision2_42_220116.png

これで、Vitis HLS 2020.2 の作業は終了し、次回からは Vitis HLS 2021.2 でプロジェクトを開いて、作業をしていく。
  1. 2022年01月15日 05:20 |
  2. Vitis_Vision
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/5472-87c5f7b1
この記事にトラックバックする(FC2ブログユーザー)