Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#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
You can’t perform that action at this time.