// // This file is part of the Bones source-to-source compiler examples. This C-code // demonstrates the use of Bones for an example (real) application: 'Fast Focus // on Structures' (FFOS). For more information on the application or on Bones // please use the contact information below. // // == More information on the FFOS application // Contact............Yifan He / Zhenyu Ye // Web address........http://zhenyu-ye.net/publications/acivs2011/yifan2011acivs.pdf // // == More information on Bones // Contact............Cedric Nugteren // Web address........http://parse.ele.tue.nl/bones/ // // == File information // Filename...........applications/ffos.c // Author.............Cedric Nugteren // Last modified on...11-October-2014 // //######################################################################## //### Includes //######################################################################## #include #include #include #include //######################################################################## //### Defines //######################################################################## #define XVECTORS 10 #define YVECTORS 10 //######################################################################## //### Forward declarations //######################################################################## void SaveBMPFile(unsigned char ** image, const char * outputdestination, int width, int height); unsigned char ** LoadBMPFile(int *width, int *height); void CPU_FindCenters(int* vector, int *coordinates, int size); void CPU_Visualize(unsigned char** image0, int* Xcoordinates, int* Ycoordinates, unsigned char **image3, int width, int height); void CPU_BCV(int *histogram, float *BCVtable, int size); //######################################################################## //### Global variables //######################################################################## int messages = 2; //######################################################################## //### Start of the main function //######################################################################## int main(void) { // Declare loop variables int i,h,w,a; // Set other variables int threshold = 0; int hist[256]; for (i=0;i<256;i++) { hist[i] = 0; } float * BCVtable = (float *)malloc(256*sizeof(float)); // Loading image0 from disk if (messages == 2) { printf("### Loading image0 from disk.\n"); } int width = 0; int height = 0; unsigned char ** image0 = LoadBMPFile(&width, &height); // Create space for image1 if (messages == 2) { printf("### Allocating space for image1.\n"); } unsigned char ** image1 = (unsigned char **)malloc(width*sizeof(*image1)); unsigned char * image1_1D = (unsigned char *)malloc(width*height*sizeof(unsigned char)); for(i=0;i= 1) { printf("### PART1: Histogramming.\n"); fflush(stdout); } #pragma scop #pragma species kernel image0[0:height-1,0:width-1]|element -> hist[0:255]|shared for (h=0;h= 1) { printf("### PART2: Search for the maximum value.\n"); fflush(stdout); } float maximum[1]; maximum[0] = 10; int length = 256; //#pragma species kernel 0:255|element -> 0:0|shared for (i=0;i maximum[0]) ? BCVtable[i] : maximum[0]; } //#pragma species endkernel maximum_1 if (messages == 2) { printf("### Maximum is %.3lf.\n",maximum[0]); fflush(stdout); } //######################################################################## //### PART3: Search for the maximum - larger synthetic example (accelerated) //######################################################################## if (messages >= 1) { printf("### PART3: Search for the maximum value (synthetic example).\n"); fflush(stdout); } int vector_size = 2097152; // 2048x1024 float* synthetic_vector = (float*)malloc(sizeof(float)*vector_size); srand(time(NULL));for (i=0;i 0:0|shared for (i=0;i result[0]) ? synthetic_vector[i] : result[0]; } //#pragma species endkernel maximum_2 if (messages == 2) { printf("### Maximum is %.3lf.\n",result[0]); fflush(stdout); } //######################################################################## //### Search for the index of the maximum (CPU) //######################################################################## if (messages == 2) { printf("### Search for the index of the maximum value.\n"); fflush(stdout); } for (i=0;i<256;i++) { if (BCVtable[i] == maximum[0]) { threshold = i; break; } } //######################################################################## //### PART4: Binarization (accelerated) //######################################################################## if (messages >= 1) { printf("### PART4: Binarization with treshold at %d.\n",threshold); fflush(stdout); } unsigned char val; #pragma scop #pragma species kernel image0[0:height-1,0:width-1]|element -> image1[0:height-1,0:width-1]|element for (h=0;h threshold) { val = 1; } else { val = 0; } image1[h][w] = val; } } #pragma species endkernel threshold #pragma endscop //######################################################################## //### PART5: Erosion 7x7 (accelerated) //######################################################################## if (messages >= 1) { printf("### PART5: Perform the erode kernel.\n"); fflush(stdout); } int condition; #pragma scop #pragma species kernel image1[7:height-8,7:width-8]|neighbourhood(-3:3,-3:3) -> image2[0:height-1,0:width-1]|element for (h=0;h= 7 && h >= 7 && w <= width-7 && h <= height-7) { condition = 1; for(a=-3;a<=3;a++) { condition = condition * image1[(h-3)][(w+a)] * image1[(h-2)][(w+a)] * image1[(h-1)][(w+a)] * image1[(h+0)][(w+a)] * image1[(h+1)][(w+a)] * image1[(h+2)][(w+a)] * image1[(h+3)][(w+a)] ; } if (condition == 1) { image2[h][w] = 255; } else { image2[h][w] = 0; } } else { image2[h][w] = 0; } } } #pragma species endkernel erosion #pragma endscop //######################################################################## //### PART6: 1D erosion(7) synthetic example (accelerated) //######################################################################## if (messages >= 1) { printf("### PART6: Perform the erode kernel (1D - synthetic).\n"); fflush(stdout); } int vector_size2 = 2097152; // 2048x1024 int* vector2a = (int*)malloc(sizeof(int)*vector_size2); int* vector2b = (int*)malloc(sizeof(int)*vector_size2); srand(time(NULL)); for (i=0;i 1) { vector2a[i] = 1; } else { vector2a[i] = 0; } } //#pragma species kernel 0:2097151|neighbourhood(-3:3) -> 0:2097151|element for (i=0;i= 7 && i <= vector_size2-7) { condition = 1; for(a=-3;a<=3;a++) { condition = condition * vector2a[i+a]; } if (condition == 1) { vector2b[i] = 255; } else { vector2b[i] = 0; } } else { vector2b[i] = 0; } } //#pragma species endkernel erosion1d // Compute a gold reference int gold = 0; int gold_condition = 1; for(a=-3;a<=3;a++) { gold_condition = gold_condition * vector2a[10+a]; } if (gold_condition == 1) { gold = 255; } if (messages == 2) { printf("### Result at index 10 is %d and should be %d.\n",vector2b[10],gold); fflush(stdout); } //######################################################################## //### PART7: Y-projection (accelerated) //######################################################################## if (messages >= 1) { printf("### PART7: Starting the Y-projection algorithm.\n"); fflush(stdout); } int result_yp; #pragma scop #pragma species kernel image2[0:height-1,0:width-1]|chunk(0:height-1,0:0) -> Yvector[0:width-1]|element for (w=0;w= 1) { printf("### PART8: Starting the X-projection algorithm.\n"); fflush(stdout); } int result_xp; #pragma scop #pragma species kernel image2[0:height-1,0:width-1]|chunk(0:0,0:width-1) -> Xvector[0:height-1]|element for (h=0;h> 24; ucaBitmapSize[2]= (ulBitmapSize & 0x00FF0000) >> 16; ucaBitmapSize[1]= (ulBitmapSize & 0x0000FF00) >> 8; ucaBitmapSize[0]= (ulBitmapSize & 0x000000FF); // Load output file fd_out = fopen(outputdestination, "wb"); // Write BMP header fprintf(fd_out,"%c%c%c%c%c%c%c%c%c%c", 66, 77, ucaBitmapSize[0], ucaBitmapSize[1], ucaBitmapSize[2], ucaBitmapSize[3], 0, 0, 0, 0); fprintf(fd_out,"%c%c%c%c%c%c%c%c%c%c", 54, 0, 0, 0, 40, 0 , 0, 0, (width & 0x00FF), (width & 0xFF00)>>8); fprintf(fd_out,"%c%c%c%c%c%c%c%c%c%c", 0, 0, (height & 0x00FF), (height & 0xFF00) >> 8, 0, 0, 1, 0, 24, 0); fprintf(fd_out,"%c%c%c%c%c%c%c%c%c%c", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); fprintf(fd_out,"%c%c%c%c%c%c%c%c%c%c", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); fprintf(fd_out,"%c%c%c%c", 0, 0 ,0, 0); // Save RGB data to output file for(y=0;y>16) != 24) { printf("***BMP load error: invalid color depth (%d)*** \n",(infoHdr.planesBitsPerPixel>>16)); exit(0); } if(infoHdr.compression) { printf("***BMP load error: compressed image***\n"); exit(0); } (*width) = infoHdr.width; (*height) = infoHdr.height; // Allocate memory to store the BMP's contents unsigned char ** image = (unsigned char **)malloc((*width) * sizeof(*image)); unsigned char * image_1D = (unsigned char *)malloc((*width) * (*height) * sizeof(unsigned char)); for(i=0; i<(*width); i++) { image[i] = &image_1D[i*(*height)]; } // Read the BMP file and store the contents fseek(fd, hdr.offset - sizeof(hdr) - sizeof(infoHdr), SEEK_CUR); for(y = 0; y < (*height); y++) { for(x = 0; x < (*width); x++) { image[x][y] = ((int)fgetc(fd)); fgetc(fd); fgetc(fd); } int over = (4 - ((*width)*3) % 4) % 4; if (over != 0) { for(x = 0; x < over; x++) { fgetc(fd); } } } // Exit the function and clean-up if(ferror(fd)) { printf("***Unknown BMP load error.***\n"); free(image[0]); free(image); exit(0); } fclose(fd); return image; } //######################################################################## //### Find the center of a projection vector (using a state machine) //######################################################################## void CPU_FindCenters(int* vector, int *coordinates, int size) { int s; int state = 0; int count = 0; int coordinate = 0; for (s=0;s 4) { // To filter out noise coordinates[coordinate] = s-(count/2); coordinate++; } } else { // I found a 255 again count++; } } } } //######################################################################## //### CPU kernel to visualize the results //######################################################################## void CPU_Visualize(unsigned char** image0, int* Xcoordinates, int* Ycoordinates, unsigned char **image3, int width, int height) { // Loop variables int h, w, x, y; // Copy the whole image for (h=0;h