FC2カウンター FPGAの部屋 2022年01月20日
fc2ブログ

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

FPGAの部屋

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

Vitis HLS 2021.2 を使用して画像ファイルを C のヘッダファイルに変換する

Vivado HLS 2019.1 を使用してBMPファイルをC のヘッダファイルに変換する”というブログを書いたが、それを Vitis HLS 2021.2 でやってみる。また、OpenCV 3.4.9 を使用するので、BMP ファイルじゃなくても問題ない。従ってBMPファイルから画像ファイルにタイトルを変更した。

ソースコードの dummy.cpp を示す。
Vitis HLS 2021.2 では、ソースコードに何らかのファイルが無いと C シミュレーションがエラーになってしまうようだ。そこでダミーのファイルを用意した。このファイルは使わない。

int dummy(){
    return 0;
}


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

// pict_header_file.cpp
// 画像を C のヘッダファイルに変換する
// 2022/01/19 by marsee

#include <iostream>
#include <stdlib.h>
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

char INPUT_PICT_FILE[] = "test2.jpg";
char OUTPUT_HEADER_FILE[] = "pict_data.h";

int main(){
    uint8_t *red, *green, *blue;
    FILE *fbmpw;

    // 画像ファイルをMat に読み込む
    cv::Mat img = cv::imread(INPUT_PICT_FILE);

    // ピクセルを入れるメモリをアロケートする
    if ((red =(uint8_t *)malloc(sizeof(uint8_t) * (img.rows * img.cols))) == NULL){
        fprintf(stderr, "Can't allocate red memory\n");
        exit(1);
    }
    if ((green =(uint8_t *)malloc(sizeof(uint8_t) * (img.rows * img.cols))) == NULL){
        fprintf(stderr, "Can't allocate green memory\n");
        exit(1);
    }
    if ((blue =(uint8_t *)malloc(sizeof(uint8_t) * (img.rows * img.cols))) == NULL){
        fprintf(stderr, "Can't allocate blue memory\n");
        exit(1);
    }

    cv::Mat_<cv::Vec3b> dst_vec3b = cv::Mat_<cv::Vec3b>(img);
    for (int y=0; y<img.rows; y++){
        for (int x=0; x<img.cols; x++){
            cv::Vec3b pixel;
            pixel = dst_vec3b(y,x);
            blue[y*img.cols+x] = pixel[0]; // blue
            green[y*img.cols+x] = pixel[1]; // green
            red[y*img.cols+x] = pixel[2]; // red
        }
    }

    // 画像データのヘッダを画像出力ファイルに書き込む
    if ((fbmpw = fopen(OUTPUT_HEADER_FILE, "w")) == NULL){
        fprintf(stderr, "Can't open bmp header file\n");
        exit(1);
    }

    fprintf(fbmpw, "// %s\n", OUTPUT_HEADER_FILE);
    time_t now = std::time(nullptr);
    struct tm* jst = std::localtime(&now);
    fprintf(fbmpw, "// %04d/%02d/%02d %02d:%02d:%02d by marsee\n", jst->tm_year+1900, jst->tm_mon+1, jst->tm_mday,
            jst->tm_hour, jst->tm_min, jst->tm_sec);
    fprintf(fbmpw, "//\n\n");

    fprintf(fbmpw, "#define X_SIZE %d\n", img.cols);
    fprintf(fbmpw, "#define Y_SIZE %d\n\n", img.rows);

    fprintf(fbmpw, "unsigned char pict_file_array[%d][%d][3] = {\n", img.rows, img.cols);
    for (int y=0; y<img.rows; y++){
        fprintf(fbmpw, "\t{");
        for (int x=0; x<img.cols; x++){
            if (x != 0)
                fprintf(fbmpw, ",");

            fprintf(fbmpw, "{%d,%d,%d}", blue[y*img.cols+x], green[y*img.cols+x], red[y*img.cols+x]);
        }
        if (y == (img.rows-1))
            fprintf(fbmpw, "}\n");
        else
            fprintf(fbmpw, "},\n");
    }
    fprintf(fbmpw, "\n};");

    fclose(fbmpw);

    return(0);
}


変換する画像ファイル test2.jpg を示す。
800 x 600 ピクセルのノイズを付加した画像ファイルだ。
Vitis_Vision2_71_220120.jpg

Vitis HLS 2021.2 で pict_header_file プロジェクトを作成した。合成しないので、使用する FPGA やボードは何でも良いのだが、xc7z020clg400-1 を指定した。
Vitis_Vision2_70_220120.png

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

-I/usr/local/include

を設定した。

Linker Flags に

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

を設定した。
Vitis_Vision2_74_220120.png

C シミュレーションを実行した。
pict_data.h が生成された。
Vitis_Vision2_72_220120.png

pict_data.h の一部を見た。
Vitis_Vision2_73_220120.png

pict_data.h の大きさは 6 MB だった。データをテキストにしているので、ファイルが大きくなるのは仕方がない。
Vitis_Vision2_75_220120.png
  1. 2022年01月20日 05:33 |
  2. Vitis HLS
  3. | トラックバック:0
  4. | コメント:0