Created
April 19, 2015 08:27
-
-
Save formalism/acce54f738c7c6069302 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <ap_int.h> | |
#define HORIZONTAL_PIXEL_WIDTH 800 | |
#define VERTICAL_PIXEL_WIDTH 600 | |
#define ALL_PIXEL_VALUE (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH) | |
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2); | |
int conv_rgb2y(int rgb); | |
void filter_line(unsigned int* lap_buf, unsigned int* fl, unsigned int* sl, unsigned int* tl){ | |
int lap_fil_val; | |
ap_uint<8> prev[3],current[3],next[3]; // 0->1ライン目, 1->2ライン目, 2->3ライン目, prev->1pixel前, current->現在, next->次pixel | |
#pragma HLS array_partition variable=prev complete dim=0 | |
#pragma HLS array_partition variable=current complete dim=0 | |
#pragma HLS array_partition variable=next complete dim=0 | |
next[0] = conv_rgb2y(fl[0]); | |
next[1] = conv_rgb2y(sl[0]); | |
next[2] = conv_rgb2y(tl[0]); | |
for (int x = 0; x < HORIZONTAL_PIXEL_WIDTH; x++){ | |
#pragma HLS pipeline | |
if (x == 0 || x == HORIZONTAL_PIXEL_WIDTH-1){ | |
lap_fil_val = 0; | |
current[0] = next[0]; | |
next[0] = conv_rgb2y(fl[1]); | |
current[1] = next[1]; | |
next[1] = conv_rgb2y(sl[1]); | |
current[2] = next[2]; | |
next[2] = conv_rgb2y(tl[1]); | |
}else{ | |
prev[0] = current[0]; | |
current[0] = next[0]; | |
next[0] = conv_rgb2y(fl[x+1]); | |
prev[1] = current[1]; | |
current[1] = next[1]; | |
next[1] = conv_rgb2y(sl[x+1]); | |
prev[2] = current[2]; | |
current[2] = next[2]; | |
next[2] = conv_rgb2y(tl[x+1]); | |
lap_fil_val = laplacian_fil(prev[0], current[0], next[0], | |
prev[1], current[1], next[1], | |
prev[2], current[2], next[2]); | |
} | |
lap_buf[x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる | |
} | |
} | |
int lap_filter_axim(int cam_addr, int lap_addr, volatile int *cam_fb, volatile int *lap_fb) | |
{ | |
#pragma HLS INTERFACE s_axilite port=cam_addr bundle=BUS_AXI4LS | |
#pragma HLS INTERFACE s_axilite port=lap_addr bundle=BUS_AXI4LS | |
#pragma HLS INTERFACE s_axilite port=return bundle=BUS_AXI4LS | |
#pragma HLS INTERFACE ap_none port=cam_addr | |
#pragma HLS INTERFACE ap_none port=lap_addr | |
#pragma HLS INTERFACE m_axi port=cam_fb depth=1920 | |
#pragma HLS INTERFACE m_axi port=lap_fb depth=1920 | |
unsigned int line_buf[3][HORIZONTAL_PIXEL_WIDTH]; | |
#pragma HLS array_partition variable line_buf block factor=3 dim=1 | |
#pragma HLS resource variable=line_buf core=RAM_2P | |
unsigned int lap_buf[HORIZONTAL_PIXEL_WIDTH]; | |
int x, y; | |
int lap_fil_val; | |
int a, b; | |
int fl, sl, tl; | |
unsigned int offset_cam_addr, offset_lap_addr; | |
int *cam_fb_addr, *lap_fb_addr; | |
int line_sel; | |
offset_cam_addr = cam_addr/sizeof(int); | |
offset_lap_addr = lap_addr/sizeof(int); | |
// RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。 | |
for (y=1, line_sel=0; y<VERTICAL_PIXEL_WIDTH-1; y++){ | |
// 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012 | |
switch(line_sel){ | |
case 1 : | |
fl = 0; sl = 1; tl = 2; | |
break; | |
case 2 : | |
fl = 1; sl = 2; tl = 0; | |
break; | |
case 3 : | |
fl = 2; sl = 0; tl = 1; | |
break; | |
default : | |
fl = 0; sl = 1; tl = 2; | |
} | |
if (y == 1){ | |
#ifndef __SYNTHESIS__ | |
printf("copy 3 lines\n"); | |
#endif | |
for (a=0; a<3; a++){ | |
// 3ライン分 | |
cam_fb_addr = (int*)(cam_fb+offset_cam_addr+(a*(HORIZONTAL_PIXEL_WIDTH))); | |
memcpy(line_buf[a], (unsigned int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int)); | |
} | |
}else{ // 最初のラインではないので、1ラインだけ読み込む。すでに他の2ラインは読み込まれている | |
cam_fb_addr = (int*)(cam_fb+offset_cam_addr+((y+1)*(HORIZONTAL_PIXEL_WIDTH))); | |
memcpy(line_buf[tl], (unsigned int*)cam_fb_addr, HORIZONTAL_PIXEL_WIDTH*sizeof(int)); | |
} | |
filter_line(lap_buf, line_buf[fl], line_buf[sl], line_buf[tl]); | |
lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(y*(HORIZONTAL_PIXEL_WIDTH))); | |
#ifndef __SYNTHESIS__ | |
printf("write back:%d\n", y); | |
#endif | |
memcpy((unsigned int*)lap_fb_addr, (unsigned int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int)); | |
line_sel++; | |
if (line_sel > 3){ | |
line_sel = 1; | |
} | |
} | |
// 最初と最後のラインは0にする | |
for (x = 0; x < HORIZONTAL_PIXEL_WIDTH; x++) | |
lap_buf[x] = 0; | |
lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(0*(HORIZONTAL_PIXEL_WIDTH))); | |
memcpy((unsigned int*)lap_fb_addr, (unsigned int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int)); | |
lap_fb_addr = (int *)(lap_fb+offset_lap_addr+(VERTICAL_PIXEL_WIDTH-1)*HORIZONTAL_PIXEL_WIDTH); | |
memcpy((unsigned int*)lap_fb_addr, (unsigned int*)lap_buf, HORIZONTAL_PIXEL_WIDTH*sizeof(int)); | |
return(1); | |
} | |
// RGBからYへの変換 | |
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits | |
// 輝度信号Yのみに変換する。変換式は、Y = 0.299R + 0.587G + 0.114B | |
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html | |
// 2013/09/27 : float を止めて、すべてint にした | |
int conv_rgb2y(int rgb){ | |
int r, g, b, y_f; | |
int y; | |
b = rgb & 0xff; | |
g = (rgb>>8) & 0xff; | |
r = (rgb>>16) & 0xff; | |
y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した | |
y = y_f >> 8; // 256で割る | |
return(y); | |
} | |
// ラプラシアンフィルタ | |
// x0y0 x1y0 x2y0 -1 -1 -1 | |
// x0y1 x1y1 x2y1 -1 8 -1 | |
// x0y2 x1y2 x2y2 -1 -1 -1 | |
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2) | |
{ | |
int y; | |
y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2; | |
if (y<0) | |
y = 0; | |
else if (y>255) | |
y = 255; | |
return(y); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment