FC2カウンター FPGAの部屋 Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加4(RGB2HSV)
fc2ブログ

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

FPGAの部屋

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

Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加4(RGB2HSV)

Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加3(SDK2)”の続き。

Vivado 2016.2 からVivado 2016.3 へアップグレード”でVivado 2016.3 にアップグレードできた。
今回は、HSV2RGB変換をARMプロセッサで動作するソフトウェアとして実装して結果を確認し、次にHSV2RGB変換時にS = V = 255 としてH を変換して結果を確認した。

SDK の画面を示す。
rgb2hsv_37_161026.png

cam_disp_lgh.elf を起動した結果を示す。元のカメラ画像だ。
rgb2hsv_34_161026.jpg

次に、HSV2RGB変換をARMプロセッサで動作するソフトウェア rgf2hsv_rev.c を実行した結果を示す。
rgb2hsv_35_161026.jpg

原画像との間に差は分からない。

HSV2RGB変換時にS = V = 255 としてH を変換するソフトウェア rgb2hsv_ho.c を実行した結果を示す。
rgb2hsv_36_161026.jpg

オレンジ色のブロアーも光が当たって白くなってしまったところは色が変わってしまうので注意が必要のようだ。

rgb2hsv_rev.c を貼っておく。

/* * rgb2hsv_rev.c * *  Created on: 2016/10/24 *      Author: Masaaki */
// ソフトウェアでHSV2RGB変換を行う

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

#include "xgabor_filter_lh.h"
#include "xdmaw4gabor.h"

#define HORIZONTAL_PIXELS    800
#define VERTICAL_LINES        600
#define PIXEL_NUM_OF_BYTES    4

#define FRAME_BUFFER_ADDRESS 0x10000000
#define ALL_DISP_ADDRESS    (HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES)

int main(){
    XGabor_filter_lh gabf;
    XDmaw4gabor xdma4g;

    XRgb2hsv_Initialize(&gabf, 0);
    XRgb2hsv_Start(&gabf);
    XRgb2hsv_EnableAutoRestart(&gabf);

    int i, j;
    int max, min;
    int h, s, v;
    int r, g, b;
    volatile int *fb_hsv, *fb_rgb;

    // axis_switch_1, 1to2 ,Select M00_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x40), 0x80000000);
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x44), 0x80000000); // disable
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x48), 0x80000000); // disable
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x4C), 0x0); // disable
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR), 0x2); // Commit registers

    // axis_switch_0, 2to1, Select S00_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR+0x40), 0x3);
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR), 0x2); // Commit registers

    // DMAW4Gabor Address set
    XDmaw4gabor_Initialize(&xdma4g, 0);
    XDmaw4gabor_Set_frame_buffer0(&xdma4g, FRAME_BUFFER_ADDRESS);
    XDmaw4gabor_Set_frame_buffer1(&xdma4g, FRAME_BUFFER_ADDRESS);

    // Bitmap display Controller Address set
    volatile int *bmdc0_axi_lites;
    volatile int *bmdc1_axi_lites;

    bmdc0_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
    bmdc1_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_1_BASEADDR;

    bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 0 start
    bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 1 start
    //bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 0 start
    //bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 1 start

    fb_hsv = (volatile int *)FRAME_BUFFER_ADDRESS;
    fb_rgb = (volatile int *)((unsigned int)FRAME_BUFFER_ADDRESS+(unsigned int)ALL_DISP_ADDRESS);

    while(1){
        for(j=0; j<VERTICAL_LINES; j++){
            for(i=0; i<HORIZONTAL_PIXELS; i++){
                h = (fb_hsv[HORIZONTAL_PIXELS*j+i]/65536) & 0x1ff;
                s = (fb_hsv[HORIZONTAL_PIXELS*j+i]/256) & 0xff;
                v = fb_hsv[HORIZONTAL_PIXELS*j+i] & 0xff;

                max = v;
                min = max - (int)(((float)s/255.0)*(float)max + 0.5); // 0.5は四捨五入

                if(h>=0 && h<60){
                    r = max;
                    g = (int)(((float)h/60.0)*(float)(max-min)+0.5) + min;
                    b = min;
                }else if(h>=60 && h<120){
                    r = (int)(((120.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                    g = max;
                    b = min;
                }else if(h>=120 && h<180){
                    r = min;
                    g = max;
                    b = (int)((((float)h-120.0)/60.0)*((float)(max-min))+0.5) + min;
                }else if(h>=180 && h<240){
                    r = min;
                    g = (int)(((240.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                    b = max;
                }else if(h>=240 && h<300){
                    r = (int)((((float)h-240.0)/60.0)*((float)(max-min))+0.5) + min;
                    g = min;
                    b = max;
                }else{// if(h<=300 && h<=360){
                    r = max;
                    g = min;
                    b = (int)(((360.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                }
                fb_rgb[HORIZONTAL_PIXELS*j+i] = (r&0xff)*65536 | (g&0xff)*256 | b&0xff;
            }
        }
        Xil_DCacheFlush();
        sleep(1);
    }

    return 0;
}


rgb2hsv_ho.c を貼っておく。

/* * rgb2hsv_ho.c * *  Created on: 2016/10/24 *      Author: ono */
// ソフトウェアでHSV2RGB変換するのだが、S=V=255として変換する。Hだけを変換。

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

#include "xgabor_filter_lh.h"
#include "xdmaw4gabor.h"

#define HORIZONTAL_PIXELS    800
#define VERTICAL_LINES        600
#define PIXEL_NUM_OF_BYTES    4

#define FRAME_BUFFER_ADDRESS 0x10000000
#define ALL_DISP_ADDRESS    (HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES)

int main(){
    XGabor_filter_lh gabf;
    XDmaw4gabor xdma4g;

    XRgb2hsv_Initialize(&gabf, 0);
    XRgb2hsv_Start(&gabf);
    XRgb2hsv_EnableAutoRestart(&gabf);

    int i, j;
    int max, min;
    int h, s, v;
    int r, g, b;
    volatile int *fb_hsv, *fb_rgb;

    // axis_switch_1, 1to2 ,Select M00_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x40), 0x80000000);
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x44), 0x80000000); // disable
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x48), 0x80000000); // disable
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x4C), 0x0); // disable
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR), 0x2); // Commit registers

    // axis_switch_0, 2to1, Select S00_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR+0x40), 0x3);
    Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR), 0x2); // Commit registers

    // DMAW4Gabor Address set
    XDmaw4gabor_Initialize(&xdma4g, 0);
    XDmaw4gabor_Set_frame_buffer0(&xdma4g, FRAME_BUFFER_ADDRESS);
    XDmaw4gabor_Set_frame_buffer1(&xdma4g, FRAME_BUFFER_ADDRESS);

    // Bitmap display Controller Address set
    volatile int *bmdc0_axi_lites;
    volatile int *bmdc1_axi_lites;

    bmdc0_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
    bmdc1_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_1_BASEADDR;

    bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 0 start
    bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 1 start
    //bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 0 start
    //bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 1 start

    fb_hsv = (volatile int *)FRAME_BUFFER_ADDRESS;
    fb_rgb = (volatile int *)((unsigned int)FRAME_BUFFER_ADDRESS+(unsigned int)ALL_DISP_ADDRESS);

    while(1){
        for(j=0; j<VERTICAL_LINES; j++){
            for(i=0; i<HORIZONTAL_PIXELS; i++){
                h = (fb_hsv[HORIZONTAL_PIXELS*j+i]/65536) & 0x1ff;

                max = 255;
                min = 0;

                if(h>=0 && h<60){
                    r = max;
                    g = (int)(((float)h/60.0)*(float)(max-min)+0.5) + min;
                    b = min;
                }else if(h>=60 && h<120){
                    r = (int)(((120.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                    g = max;
                    b = min;
                }else if(h>=120 && h<180){
                    r = min;
                    g = max;
                    b = (int)((((float)h-120.0)/60.0)*((float)(max-min))+0.5) + min;
                }else if(h>=180 && h<240){
                    r = min;
                    g = (int)(((240.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                    b = max;
                }else if(h>=240 && h<300){
                    r = (int)((((float)h-240.0)/60.0)*((float)(max-min))+0.5) + min;
                    g = min;
                    b = max;
                }else{// if(h<=300 && h<=360){
                    r = max;
                    g = min;
                    b = (int)(((360.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                }
                fb_rgb[HORIZONTAL_PIXELS*j+i] = (r&0xff)*65536 | (g&0xff)*256 | b&0xff;
            }
        }
        Xil_DCacheFlush();
        sleep(1);
    }

    return 0;
}

  1. 2016年10月26日 04:57 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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