- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am currently developing on the FPGA Cyclone V board. I have successfully ran the 3x3 sobel filter kernel example, and have expanded this to include a 5x5 example successfully also. I decided I would like to include a median filter to remove noise prior to doing the 5x5 sobel filter. I have also successfully got an output from the median filter. However when I try to implement the two, I get strange results. The code is below.
# include "../host/inc/imageDims.h"
__kernel
void laplacian33(global unsigned int * restrict frame_in,
global unsigned char * restrict frame_out,
const int totalpixels)
{
//Define convolution matrix
int h_n_x = {{-1,-2,-1},{0,0,0},{1,2,1}};
int h_n_y = {{-1,0,1},{-2,0,2},{-1,0,1}};
char set_white = 0xff;
char set_black = 0x00;
// Pixel buffer of 2 columns and 3 extra pixels
int pix_buff;
// Initial iterations initialize the pixel buffer
int count = -(3 * COLS + 3);
//Iterator of the output index for greyscale PGM image
int outIndex = 0;
while (count != totalpixels) {
//Fill pixel buffer
# pragma unroll
for (int i = 3 * COLS + 2; i > 0; --i) {
pix_buff = pix_buff;
}
pix_buff = count >= 0 ? frame_in : 0;
//Initialise greyscale variable.
char grey_scale_x = 0x00;
char grey_scale_y = 0x00;
//Compute one convolution each cycle
# pragma unroll
for (int filterRow = 0; filterRow < 3; ++filterRow) {
# pragma unroll
for (int filterCol = 0; filterCol < 3; ++filterCol) {
//Get the current pixel
unsigned int pixel = pix_buff;
unsigned char b = pixel & 0xff0000;
unsigned char g = pixel & 0x00ff00;
unsigned char r = pixel & 0x0000ff;
//Approximate version, simply apply a ratio and shift
unsigned char luma_apprx = ((2 * r) + b + (3 * g)) >> 3;
//Typecast luma as a char and perform convolution
grey_scale_x += (char)luma_apprx*h_n_x;
grey_scale_y += (char)luma_apprx*h_n_y;
}
}
int sobel_mag = abs(grey_scale_x) + abs(grey_scale_y);
if(sobel_mag > 0xff) sobel_mag = set_white;
else if(sobel_mag < 0x00) sobel_mag = set_black;
if(outIndex != totalpixels) {
frame_out = sobel_mag; //Write byte, iterate index
}
count++; //Iterate overall count
}
}
__kernel
void laplacian55(global unsigned int * restrict frame_in,
global unsigned char * restrict frame_out, global unsigned char * restrict frame_median,
const int totalpixels)
{
//Define convolution matrix
int h_n_x = {{2,2,4,2,2},
{1,1,2,1,1},
{0,0,0,0,0},
{-1,-1,-2,-1,-1},
{-2,-2,-4,-2,-2}};
int h_n_y = {{2,1,0,-1,-2},
{2,1,0,-1,-2},
{4,2,0,-2,-4},
{2,1,0,-1,-2},
{2,1,0,-1,-2}};
unsigned char median_matrix;
int height = 5;
int width = 5;
int value = 0;
int median = 0;
unsigned char array;
char set_white = 0xff;
char set_black = 0x00;
// Pixel buffer.
int pix_buff;
int pix_buff_2;
// Initial iterations initialize the pixel buffer
int count = -(5 * COLS + 3);
int sobelCount = -(5 * COLS + 3);
//Iterator of the output index for greyscale PGM image
int sobel_outIndex = 0;
int outIndex = 0;
//Initialise greyscale variable.
char grey_scale_x = 0x00;
char grey_scale_y = 0x00;
int filterRow;
int filterCol;
unsigned char sobelPixel = 0x00;
while (count != totalpixels) {
//Fill pixel buffer
# pragma unroll
for (int i = 5 * COLS + 2; i > 0; --i) {
pix_buff = pix_buff;
}
pix_buff = count >= 0 ? frame_in : 0;
//Get values and find median each cycle
# pragma unroll
for (filterRow = 0; filterRow < 5; ++filterRow) {
# pragma unroll
for (filterCol = 0; filterCol < 5; ++filterCol) {
//Get the current pixel
unsigned int pixel = pix_buff;
//Retrieve the individual bytes of pixel by masking.
unsigned char b = pixel & 0xff0000;
unsigned char g = pixel & 0x00ff00;
unsigned char r = pixel & 0x0000ff;
//Convert 3 bytes of RGB --> 1 byte of greyscale data
unsigned char luma_apprx = ((2 * r) + b + (3 * g)) >> 3;
//Store appropriate grey level in median matrix
median_matrix = luma_apprx;
}
}
//Convert 2d array to 1d vector
for(int rows = 0; rows < 5; rows++) {
for(int cols = 0; cols < 5; cols++) {
array = median_matrix;
}
}
//Sort array
for(int x = 0; x < 25; x++){
for(int y = 0; y < 24; y++){
if(array>array){
int temp = array;
array = array;
array = temp;
}
}
}
//Get median
median = array;
//Write the total number of greyscale bytes
if(outIndex != totalpixels) {
frame_median = median; //Write byte, iterate index
}
count++; //Iterate overall count
}
//Do the same, but this time use sobel filter..
while (sobelCount != totalpixels) {
//Initialise pixel buffer for sobel
# pragma unroll
for (int z = 5 * COLS + 2; z > 0; --z) {
pix_buff_2 = pix_buff_2;
}
//Fill buffer with median data
pix_buff_2 = sobelCount >= 0 ? frame_median : 0;
//Compute one convolution each cycle
# pragma unroll
for (filterRow = 0; filterRow < 5; ++filterRow) {
# pragma unroll
for (filterCol = 0; filterCol < 5; ++filterCol) {
//Get the current pixel
sobelPixel = pix_buff_2;
grey_scale_x += (char)sobelPixel*h_n_x;
grey_scale_y += (char)sobelPixel*h_n_y;
}
}
//Threshold
int magnitude = abs(grey_scale_x) + abs(grey_scale_y);
if(magnitude > 255) magnitude = set_white;
else if(magnitude < 0) magnitude = set_black;
//Write the total number of greyscale bytes
if(sobel_outIndex != totalpixels) {
frame_out = magnitude;
}
sobelCount++; //Iterate overall count
}
}
I think I have pinpointed the problem to be with the line of code: sobelPixel = pix_buff_2;
Since changing this makes the output look different each time. I think this is because of the "boundary pixels", so the image reduces in size after the median filter, and there are no longer COLS number of columns in the resulting image to be processed by the sobel filter. However, I am struggling to find the correct algorithm to index the "current pixel" to get the correct filtered output. Could anyone please assist with this bug? Kind regards
- Tags:
- OpenCL™
Link Copied
0 Replies
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page