I have been trying to implement an image processing algorithm (blurring an image) on my MicroBlaze based design. My block design is shown below:
And here is my code:
#include <stdlib.h>
#include <sleep.h>
#include <xil_types.h>
#include <xparameters.h>
#include <xgpio.h>
#include <xuartlite.h>
#include "platform.h"
#include "image.h"
#define LED_CHANNEL 1
//Gpio and Uart Instances
XGpio Gpio;
XUartLite uart;
int main() {
init_platform();
//Width, Height and total number of pixels
u16 WIDTH = 400;
u16 HEIGHT = 400;
u32 PIXELS = WIDTH*HEIGHT;
//Initialize the Gpio and set data direction for the led channel as output
XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
XGpio_SetDataDirection(&Gpio, LED_CHANNEL, 0b0000);
//First LED is turned on to depict start of program
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0b1000);
//Allocate memory for Blurred Image pixels
u8 **BLUR_IMAGE = (u8**) malloc(160000*sizeof(u8*));
for(u32 i=0; i<PIXELS; i++) {
BLUR_IMAGE[i] = (u8*) malloc(3*sizeof(u8));
}
//Algorithm to get the blurred image
for(u16 i=0; i<HEIGHT; i++) {
for(u16 j=0; j<WIDTH; j++) {
//Coordinates of the (5x5) pixel matrix
u16 start_corner_row = (0>i-2) ? 0 : i-2;
u16 start_corner_col = (0>j-2) ? 0 : j-2;
u16 end_corner_row = (HEIGHT-1<i+2) ? HEIGHT-1 : i+2;
u16 end_corner_col = (WIDTH-1<j+2) ? WIDTH-1 : j+2;
//Represents the three R,G,B values of a pixel
u16 blur_R = 0;
u16 blur_G = 0;
u16 blur_B = 0;
//Adding all the values of R,G,B layers of the pixels in the pixel matrix
for(u16 m=start_corner_row; m<=end_corner_row; m++) {
for(u16 n=start_corner_col; n<=end_corner_col; n++) {
u32 pixel_ind = m*WIDTH + n;
blur_R += IMAGE[pixel_ind][0];
blur_G += IMAGE[pixel_ind][1];
blur_B += IMAGE[pixel_ind][2];
}
}
//Calculating average
blur_R /= 25;
blur_G /= 25;
blur_B /= 25;
//Assigning to the BLUR_IMAGE variable
BLUR_IMAGE[i*WIDTH + j][0] = blur_R;
BLUR_IMAGE[i*WIDTH + j][1] = blur_G;
BLUR_IMAGE[i*WIDTH + j][2] = blur_B;
}
}
//Second LED is turned on to depict end of image processing
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0b1100);
//Represents 50% of total pixel count
u32 percent_50 = PIXELS/2;
//Initialize the UART
XUartLite_Initialize(&uart, XPAR_UARTLITE_0_DEVICE_ID);
//Sending the blurred pixels 3 bytes at a time
for(u32 i=0; i<PIXELS; i++) {
XUartLite_Send(&uart, BLUR_IMAGE[i], 3);
//Third LED is turned on to depict that 50% of pixels have been transmitted
if(i>percent_50)
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0b1110);
//Delay of 50 us to let the receiver capture the data correctly
usleep(50);
}
//Fourth LED is turned on to depict that all the pixels have been sent
XGpio_DiscreteWrite(&Gpio, LED_CHANNEL, 0b1111);
cleanup_platform();
return 0;
}
I have stored the pixel data of my image in an array and included it in my main source file:
Then I am trying to implement a sliding window approach to blur the image. The blurred image is to be stored in another array "BLUR_IMAGE". Then I am transferring this "BLUR_IMAGE" to my PC over uartlite. The problem is that the data that I am receiving on my PC has same elements for each pixel as shown below:
At first, I though there is some problem while sending the data over uartlite. So, I tried to send the "IMAGE" array over uartlite and I received it correctly. Then, I though there might be some problem with my algorithm. So, I ran the same algorithm on my PC and it could successfully blur the image and write it to a file.
Then, I commented out the algorithm part and the uartlite part. And tried to assign "BLUR_IMAGE" some constant values {1,2,3} to each element and then print it on vitis serial terminal using xil_printf(). But on the terminal it didn't print {1,2,3}. Instead, it printed {28,222,192} as I was receiving over uartlite. So, I think there is some problem with the way I am declaring my array or the way I am assigning values to it.
Can anybody suggest me some solutions?