FC2カウンター FPGAの部屋 Vitis Vision Library の medianblur を ZYBO Z7-20 で使ってみる3
fc2ブログ

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

FPGAの部屋

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

Vitis Vision Library の medianblur を ZYBO Z7-20 で使ってみる3

AXI4 Master 版のメディアン・フィルタと XF_8UC3 を XF_8UC4 に変換する IP を使用して、メディアン・フィルタ処理後の画像をディスプレイに出力するシステムを作成しようということで、前回は、タイミングエラーを解消して、ビットストリームの生成が成功して、XSA ファイルを生成した。今回は、Vitis 2020.2 を立ち上げて、プラットフォームとアプリケーション・プロジェクトを作成し、実機検証を行う。

Vitis 2020.2 を立ち上げて、前回生成した median_v_bd_wrapper.xsa ファイルを元に、median_v_bd_wrapper プラットフォームを作成し、median_vision アプリケーション・プロジェクトを作成した。

画像をヘッダに変換した bmp_data.h を用意して、アプリケーション・ソフトウェアの median_vision.c を作成した。
median_vision_15_210119.png

median_vision.c のコードを貼っておく。

// median_vision.c
// 2021/01/16 by marsee
//

#include <stdio.h>
#include <stdint.h>
#include "xil_io.h"
#include "xparameters.h"

#include "xmedian_blur_accel.h"
#include "xxf_8uc3_2rgb.h"

#include "bmp_data.h"

#define ORG_PICT_XF_8UC4_ADDR   0x10000000
#define ORG_PICT_XF_8UC3_ADDR   0x10200000
#define FILTER_XF_8UC3_ADDR     0x10400000
#define FILTER_XF_8UC4_ADDR     0x10600000

#define HORIZONTAL_PIXELS   800
#define VERTICAL_LINES      600

int bmp_write_xf_8uc3(uint32_t xf_8uc4_addr, uint32_t xf_8uc3_addr);
void Xil_DCacheFlush(void);

int main(){
    XMedian_blur_accel XMedian_blur_accel_ap;
    XXf_8uc3_2rgb XXf_8uc3_2rgb_ap;
    int inbyte_in;

    XMedian_blur_accel_Initialize(&XMedian_blur_accel_ap, 0);
    XXf_8uc3_2rgb_Initialize(&XXf_8uc3_2rgb_ap, 0);

    XMedian_blur_accel_Set_rows(&XMedian_blur_accel_ap, (u32)VERTICAL_LINES);
    XMedian_blur_accel_Set_cols(&XMedian_blur_accel_ap, (u32)HORIZONTAL_PIXELS);
    XXf_8uc3_2rgb_Set_rows(&XXf_8uc3_2rgb_ap, (u32)VERTICAL_LINES);
    XXf_8uc3_2rgb_Set_cols(&XXf_8uc3_2rgb_ap, (u32)HORIZONTAL_PIXELS);

    XMedian_blur_accel_Set_img_in(&XMedian_blur_accel_ap, (u32)ORG_PICT_XF_8UC3_ADDR);
    XMedian_blur_accel_Set_img_out(&XMedian_blur_accel_ap, (u32)FILTER_XF_8UC3_ADDR);
    XXf_8uc3_2rgb_Set_p_src(&XXf_8uc3_2rgb_ap, (u32)FILTER_XF_8UC3_ADDR);
    XXf_8uc3_2rgb_Set_p_dst(&XXf_8uc3_2rgb_ap, (u32)FILTER_XF_8UC4_ADDR);

    bmp_write_xf_8uc3(ORG_PICT_XF_8UC4_ADDR, ORG_PICT_XF_8UC3_ADDR);
    Xil_DCacheFlush();

    XMedian_blur_accel_Start(&XMedian_blur_accel_ap);
    while(!XMedian_blur_accel_IsDone(&XMedian_blur_accel_ap));

    XXf_8uc3_2rgb_Start(&XXf_8uc3_2rgb_ap);
    while(!XXf_8uc3_2rgb_IsDone(&XXf_8uc3_2rgb_ap));

    Xil_Out32(XPAR_BITMAP_DISP_CNTRLER_0_BASEADDR, ORG_PICT_XF_8UC4_ADDR);

    while(1){
        printf("\nPlease input <0> or <1> (<q> : exit) = ");
        fflush(stdout);
        inbyte_in = inbyte();
        printf("%c", inbyte_in);
        fflush(stdout);
        switch(inbyte_in) {
            case '0': //bmp image
                Xil_Out32(XPAR_BITMAP_DISP_CNTRLER_0_BASEADDR, ORG_PICT_XF_8UC4_ADDR);
                break;
            case '1': // Laplacian filter
                Xil_Out32(XPAR_BITMAP_DISP_CNTRLER_0_BASEADDR, FILTER_XF_8UC4_ADDR);
                break;
            case 'q': // exit
                return(0);
        }
    }
}

int bmp_write_xf_8uc3(uint32_t xf_8uc4_addr, uint32_t xf_8uc3_addr){
    uint32_t pix[4];

    for(int y=0; y<VERTICAL_LINES; y++){
        for(int x=0; x<HORIZONTAL_PIXELS; x++){
            int xf_8uc4 = 0xff000000 + ((uint32_t)bmp_file_array[y][x][2]<<16)
                    +((uint32_t)bmp_file_array[y][x][1]<<8)+(uint32_t)bmp_file_array[y][x][0];
            Xil_Out32(xf_8uc4_addr+(y*HORIZONTAL_PIXELS+x)*sizeof(uint32_t), xf_8uc4);

            switch((x+y*HORIZONTAL_PIXELS)%4){
            case 0 :
                pix[0] = xf_8uc4;
                break;
            case 1 :
                pix[1] = xf_8uc4;
                Xil_Out32(xf_8uc3_addr, ((pix[1]&0xff)<<24)+(pix[0]&0xffffff));
                xf_8uc3_addr += sizeof(uint32_t);
                break;
            case 2 :
                pix[2] = xf_8uc4;
                Xil_Out32(xf_8uc3_addr, ((pix[2]&0xffff)<<16)+((pix[1]&0xffff00)>>8));
                xf_8uc3_addr += sizeof(uint32_t);
                break;
            default : // 3
                pix[3] = xf_8uc4;
                Xil_Out32(xf_8uc3_addr, ((pix[3]&0xffffff)<<8)+((pix[2]&0xff0000)>>16));
                xf_8uc3_addr += sizeof(uint32_t);
                break;
            }
        }
    }
    return(0);
}


ビルドすると median_vision.elf ができた。

ZYBO Z7-20 を接続して、電源ON した。

ターミナルで sudo gtkterm を入力して、 gtkterm を立ち上げて、 115200 bps, 8bit, 1 stop bit に設定した。

Assistant ウインドウの median_vision_system -> median_vision -> Debug を右クリックし、右クリックメニューから Run -> Launch on Hardware (Single Application Debug) を選択して、アプリケーションを起動した。

gtkterm に表示されている。
0 を入力すると元画像で、 1 を入力するとメディアン・フィルタ処理されているはずだ。
median_vision_16_210119.png

最初に表示された元画像は正常に表示されている。 gtkterm で 0 を入力しても同様だ。
ノイズが追加されているのが分かると思う。
median_vision_17_210119.jpg

gtkterm で 1 を入力したところ、メディアン・フィルタ処理画像が表示された。成功だ。
元画像のノイズが取り除かれている。
median_vision_19_210119.jpg
  1. 2021年01月19日 05:04 |
  2. Vitis_Vision
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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