FC2カウンター FPGAの部屋 2020年02月22日
FC2ブログ

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

FPGAの部屋

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

Vivado HLS 2019.2 で xfOpenCV を使用する3(sobel filter 1)

Vivado HLS 2019.2 で xfOpenCV を使用する2(dillation 2)”の続き。

前回は、xfOpenCV の dillation をやったが、今回は、xfOpenCV の xfopencv/examples/sobelfilter をやってみようと思う。ただし、この soblefilter は xf::Mat のインターフェースなので、 AXI4-Stream インターフェースに変更した。更に現状の解像度では、Ultra96 のリソースに入らないので、画像のサイズを縮小した。

変更したソースコードの xf_soble.cpp を示す。

// xf_sobel.cpp
// 2020/02/13 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

#include "xf_sobel_config.h"
#include "common/xf_infra.h"

void xf_sobel(hls::stream< ap_axiu<8,1,1,1> >& _src,hls::stream< ap_axiu<8,1,1,1> >& _dst,int height,int width){
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE axis register both  port=_src
#pragma HLS INTERFACE axis register both  port=_dst

     xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> imgInput1(height,width);
     xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> dstgx(height,width);
     xf::Mat<XF_8UC1, HEIGHT, WIDTH, NPC1> dstgy(height,width);

#pragma HLS stream variable=imgInput1.data dim=1 depth=1
#pragma HLS stream variable=imgOutput1.data dim=1 depth=1
#pragma HLS dataflow

    xf::AXIvideo2xfMat(_src, imgInput1);

    sobel_accel(imgInput1,dstgx, dstgy);

    xf::xfMat2AXIvideo(dstgx, _dst);
}


テストベンチ xf_sobel_tb.cpp のコードを示す。

// xf_sobel_tb.cpp
// 2020/02/13 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

#include "xf_headers.h"
#include "xf_sobel_config.h"
#include "common/xf_infra.h"
#include "common/xf_axi.h"

void xf_sobel(hls::stream< ap_axiu<8,1,1,1> >& _src,hls::stream< ap_axiu<8,1,1,1> >& _dst,int height,int 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
    in_img = cv::imread(argv[1], 0);
    if (in_img.data == NULL)
    {
        fprintf(stderr,"Cannot open image at %s\n", argv[1]);
        return 0;
    }
    // create memory for output images
    ocv_ref.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);

    uint16_t height = in_img.rows;
    uint16_t width = in_img.cols;

    /////////////////   Opencv  Reference  ////////////////////////
    cv::Sobel(in_img, ocv_ref, CV_8UC1, 1, 0, 3);
    cv::imwrite("out_ocv.jpg", ocv_ref);

    hls::stream< ap_axiu<8,1,1,1> > _src,_dst;

    cvMat2AXIvideoxf<NPC1>(in_img, _src);
    xf_sobel(_src, _dst, height, width);
    AXIvideo2cvMatxf<NPC1>(_dst, in_img1);

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

    cv::absdiff(ocv_ref, in_img1, diff);
    cv::imwrite("out_error.jpg", diff);

    // Find minimum and maximum differences.
        double minval=256,maxval=0;
    int cnt = 0;
    for (int i=0; i<in_img.rows; i++)
    {
        for(int j=0; j<in_img.cols; j++)
        {
            uchar v = diff.at<uchar>(i,j);
            if (v>0)
                cnt++;
            if (minval > v)
                minval = v;
            if (maxval < v)
                maxval = v;
        }
    }

    float err_per = 100.0*(float)cnt/(in_img.rows*in_img.cols);
    fprintf(stderr,"Minimum error in intensity = %f\n Maximum error in intensity = %f\n Percentage of pixels above error threshold = %f\n",minval,maxval,err_per);

    if(err_per > 0.3f)
        return 1;


    return 0;

}


Vivado HLS 2019.2 で Ultra96-V2 用の sobel_filter プロジェクトを作成して、そこに xfopencv/examples/sobelfilter ディレクトリから、その他、 xf_config_params.h, xf_headers.h, xf_sobel_accel.cpp, xf_sobel_config.h を持ってきてある。
xfOpenCV_20_200222.png

ただし、 xf_sobel_config.h は Ultra96-V2 に入らないので、WIDTH を 800 に HEIGHT を 600 に変更してある。
xfOpenCV_21_200222.png
  1. 2020年02月22日 09:52 |
  2. reVISION, xfOpenCV
  3. | トラックバック:0
  4. | コメント:0