FC2カウンター FPGAの部屋 XF_8UC3 を XF_8UC4 に変換する xf_8uc3_2rgb プロジェクトを作成する1
fc2ブログ

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

FPGAの部屋

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

XF_8UC3 を XF_8UC4 に変換する xf_8uc3_2rgb プロジェクトを作成する1

もうだいぶ、Vitis Vision Library には嫌気が差してきたのだが、最後に XF_8UC3 を XF_8UC4 に変換する xf_8uc3_2rgb プロジェクトを作成してみようと思う。
xf_8uc3_2rgb プロジェクトを何で作るのか?だが、とりあえずは Vitis HLS 2020.2 でやってみよう。

まずは、 ソースコードの xf_8uc3_2rgb.cpp を示す。

// xf_8uc3_2rgb.cpp
// 2021/01/12 by marsee
// 2021/01/12: for Vitis HLS 2020.2
//

#include "ap_int.h"
#include "hls_stream.h"

int dmar2axis(ap_uint<32>* _src, int rows, int cols, hls::stream<ap_uint<32> >& axis_out);
int xf_8uc3_2axis(hls::stream<ap_uint<32> >& axis_in, int rows, int cols, hls::stream<ap_uint<32> >& axis_out);
int axis2dmaw(hls::stream<ap_uint<32> >& axis_in, int rows, int cols, ap_uint<32>* _dst);

#define DEBUG

int xf_8uc3_2rgb(ap_uint<32>* _src, int rows, int cols, ap_uint<32>* _dst){
#pragma HLS DATAFLOW
#pragma HLS INTERFACE m_axi depth=16384 bundle=gmem port=_dst offset=slave
#pragma HLS INTERFACE s_axilite port=cols
#pragma HLS INTERFACE s_axilite port=rows
#pragma HLS INTERFACE m_axi depth=12288 bundle=gmem port=_src offset=slave
#pragma HLS INTERFACE s_axilite port=return

    hls::stream<ap_uint<32> > axis0, axis1;

    dmar2axis(_src, rows, cols, axis0);
    xf_8uc3_2axis(axis0, rows, cols, axis1);
    axis2dmaw(axis1, rows, cols, _dst);

    return(0);
}

int dmar2axis(ap_uint<32>* _src, int rows, int cols, hls::stream<ap_uint<32> >& axis_out){
    const int rows_cols_limit = (int)((float)rows * (float)cols * 3.0/4.0 + 0.7);
    ap_uint<32> pix;
    //printf("rows_cols_limit = %d\n",rows_cols_limit);

    LOOP_dr2a: for(int xy=0; xy<rows_cols_limit; xy++){
#pragma HLS PIPELINE II=1
#pragma HLS LOOP_TRIPCOUNT avg=360000 max=360000 min=360000
        pix = _src[xy];
        axis_out << pix;
#ifdef DEBUG
        if(xy < 10)
            printf("%x\n", (unsigned int)pix);
#endif
    }
    return(0);
}

int xf_8uc3_2axis(hls::stream<ap_uint<32> >& axis_in, int rows, int cols, hls::stream<ap_uint<32> >& axis_out){
    ap_uint<32> rgb[3];
    ap_uint<32> pix;
    const int rows_cols_limit = rows * cols;

    LOOP_x2s:for(int xy=0; xy<rows_cols_limit; xy++){
#pragma HLS PIPELINE II=1
#pragma HLS LOOP_TRIPCOUNT avg=480000 max=480000 min=480000
        switch(xy%4){
        case 0 :
            axis_in >> rgb[0];
            pix = (rgb[0] & 0xffffff) + 0xff000000;
            axis_out << pix;
            break;
        case 1 :
            axis_in >> rgb[1];
            pix = ((rgb[1] & 0xffff)<<8) + ((rgb[0] & 0xff000000)>>24) + 0xff000000;
            axis_out << pix;
            break;
        case 2 :
            axis_in >> rgb[2];
            pix = ((rgb[2] & 0xff)<<16) + ((rgb[1] & 0xffff0000)>>16) + 0xff000000;
            axis_out << pix;
            break;
        default : // 3
            pix = ((rgb[2] & 0xffffff00)>>8) + 0xff000000;
            axis_out << pix;
            break;
        }
    }
    return(0);
}

int axis2dmaw(hls::stream<ap_uint<32> >& axis_in, int rows, int cols, ap_uint<32>* _dst){
    const int rows_cols_limit = rows * cols;
    ap_uint<32> pix;

#ifdef DEBUG
    printf("\n");
#endif

    LOOP_a2dw:for(int xy=0; xy<rows_cols_limit; xy++){
#pragma HLS PIPELINE II=1
#pragma HLS LOOP_TRIPCOUNT avg=480000 max=480000 min=480000
        axis_in >> pix;
        _dst[xy] = pix;
#ifdef DEBUG
        if(xy < 10)
            printf("%x\n", (unsigned int)pix);
#endif
    }
    return(0);
}


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

// xf_8uc3_2rgb_tb.cpp
// 2021/01/12 by marsee
//

#include "ap_int.h"
#include "hls_stream.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

int xf_8uc3_2rgb(ap_uint<32>* _src, int rows, int cols, ap_uint<32>* _dst);

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <INPUT IMAGE>", argv[0]);
        exit(1);
    }

    cv::Mat in_img, out_img, conv_img;

    in_img = cv::imread(argv[1], 1); // reading in the color image

    if (in_img.data == NULL) {
        fprintf(stderr, "ERROR: Cannot open image %s\n ", argv[1]);
        exit(1);
    }

    out_img.create(in_img.rows, in_img.cols, CV_8UC4);
    conv_img.create(in_img.rows, in_img.cols, CV_8UC3);

    xf_8uc3_2rgb((ap_uint<32> *)in_img.data, in_img.rows, in_img.cols, (ap_uint<32> *)out_img.data);
    cv::cvtColor(out_img, conv_img, cv::COLOR_BGRA2BGR);

    cv::imwrite("output.png", conv_img);

    return(0);
}


Vitis HLS 2020.2 の xf_8uc3_2rgb プロジェクトを示す。
xf_8uc3_2rgb_1_210114.png

xf_8uc3_2rgb.cpp の

#define DEBUG

を生かすと XF_8UC3 と XF_8UC4 の最初の 10 個のデータを表示する。
C コードの合成の時は、コメントにする。
  1. 2021年01月14日 04:42 |
  2. Vitis_Vision
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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