| 9 | | |
|---|
| 10 | | |
|---|
| 11 | | /* simple hello world, showing features and compiling*/ |
|---|
| | 9 | #include "main.h" |
|---|
| | 10 | |
|---|
| | 11 | |
|---|
| | 12 | /* ---global variables----*/ |
|---|
| | 13 | |
|---|
| | 14 | // kind of buffer to get the image rows from fifo to compute integral image |
|---|
| | 15 | cc3_image_t cc3_img_tmp; |
|---|
| | 16 | |
|---|
| | 17 | // keep track of detected faces |
|---|
| | 18 | uint8_t cc3_num_detected_faces = 0; |
|---|
| | 19 | |
|---|
| | 20 | // row counter in the integral image to denote the current "top row" |
|---|
| | 21 | // i.e. the row for which the sub-windows are being evaluated for features |
|---|
| | 22 | uint8_t cc3_row_counter_ii; |
|---|
| | 23 | |
|---|
| | 24 | // row counter in the actual but cropped image (i.e. with top & bottom offset) |
|---|
| | 25 | uint8_t cc3_row_counter_cropped_img; |
|---|
| | 26 | |
|---|
| | 27 | // row counter in the actual full image |
|---|
| | 28 | uint16_t cc3_row_counter_actual_img; |
|---|
| | 29 | |
|---|
| | 30 | // integral image counter (for many rows, integral image has been calculated) |
|---|
| | 31 | uint16_t cc3_row_counter_calc_ii; |
|---|
| | 32 | |
|---|
| | 33 | uint32_t mean_val; // mean for a subwinow |
|---|
| | 34 | uint64_t sum_pix; // sum of pixels in a sub-window |
|---|
| | 35 | uint64_t sum_pix_sq; // sum of squares of pixels in a subwindow |
|---|
| | 36 | uint32_t std; // standard deviation |
|---|
| | 37 | uint64_t var; // variance |
|---|
| | 38 | |
|---|
| | 39 | // array to store rows while transfering b/w fifo and ii |
|---|
| | 40 | static uint8_t image_row[176*3]; |
|---|
| | 41 | |
|---|
| | 42 | |
|---|
| | 43 | FILE* fp; |
|---|
| | 44 | |
|---|
| | 45 | // function to get the current segment from the actual image |
|---|
| | 46 | void cc3_get_curr_segment() |
|---|
| | 47 | { |
|---|
| | 48 | cc3_pixel_t pix_temp; |
|---|
| | 49 | |
|---|
| | 50 | |
|---|
| | 51 | if (cc3_row_counter_cropped_img == 0) // first time |
|---|
| | 52 | { |
|---|
| | 53 | // load the upper "CC3_INTEGRAL_IMG_HEIGHT" rows |
|---|
| | 54 | for (uint8_t i = 0; i < CC3_INTEGRAL_IMG_HEIGHT; i++) |
|---|
| | 55 | { |
|---|
| | 56 | // get a row.. |
|---|
| | 57 | cc3_pixbuf_read_rows(cc3_img_tmp.pix, cc3_img_tmp.width, cc3_img_tmp.height); |
|---|
| | 58 | |
|---|
| | 59 | // copy the first pixel |
|---|
| | 60 | cc3_get_pixel(&cc3_img_tmp, 0, 0, &pix_temp); |
|---|
| | 61 | cc3_integral_image[i][0] = pix_temp.channel[1]; // only green channel |
|---|
| | 62 | // cc3_integral_image[i][0] = (3*pix_temp.channel[0]+6*pix_temp.channel[1]+pix_temp.channel[2])/10; // rgb->gray |
|---|
| | 63 | |
|---|
| | 64 | printf("writing to file %u \n\r", i); |
|---|
| | 65 | fprintf(fp, "%d ", cc3_integral_image[i][0]); |
|---|
| | 66 | printf("wrot to file %u \n\r", i); |
|---|
| | 67 | |
|---|
| | 68 | // start copying from the next pixel and calculate cumulative sum at the same time |
|---|
| | 69 | for (uint16_t j = 1; j < cc3_img_tmp.width; j++) |
|---|
| | 70 | { |
|---|
| | 71 | cc3_get_pixel(&cc3_img_tmp, j, 0, &pix_temp); |
|---|
| | 72 | cc3_integral_image[i][j] = pix_temp.channel[1]; // only green channel |
|---|
| | 73 | // cc3_integral_image[i][j] = (3*pix_temp.channel[0]+6*pix_temp.channel[1]+pix_temp.channel[2])/10; // rgb->gray |
|---|
| | 74 | fprintf( fp,"%d ",cc3_integral_image[i][j] ); |
|---|
| | 75 | |
|---|
| | 76 | // compute cumulative sum across the row |
|---|
| | 77 | cc3_integral_image[i][j] += cc3_integral_image[i][j-1]; |
|---|
| | 78 | } |
|---|
| | 79 | fprintf( fp, "\n" ); |
|---|
| | 80 | } |
|---|
| | 81 | |
|---|
| | 82 | // find cumulative sum along columns to complete the integral image computation |
|---|
| | 83 | for (uint16_t j = 0; j < CC3_INTEGRAL_IMG_WIDTH; j++) |
|---|
| | 84 | { |
|---|
| | 85 | for (uint16_t i = 1; i < CC3_INTEGRAL_IMG_HEIGHT; i++) // start from second row |
|---|
| | 86 | { |
|---|
| | 87 | cc3_integral_image[i][j]+=cc3_integral_image[i-1][j]; |
|---|
| | 88 | } |
|---|
| | 89 | } |
|---|
| | 90 | |
|---|
| | 91 | |
|---|
| | 92 | // printf the integral image |
|---|
| | 93 | for (uint16_t j = 0; j < CC3_INTEGRAL_IMG_HEIGHT; j++) |
|---|
| | 94 | { |
|---|
| | 95 | for (uint16_t i = 0; i < CC3_INTEGRAL_IMG_WIDTH; i++) |
|---|
| | 96 | { |
|---|
| | 97 | // printf("%ld ", cc3_integral_image[j][i] ); |
|---|
| | 98 | } |
|---|
| | 99 | // printf("\n\r"); |
|---|
| | 100 | } |
|---|
| | 101 | |
|---|
| | 102 | } |
|---|
| | 103 | |
|---|
| | 104 | else |
|---|
| | 105 | { |
|---|
| | 106 | // get a new row |
|---|
| | 107 | cc3_pixbuf_read_rows(cc3_img_tmp.pix, cc3_img_tmp.width, cc3_img_tmp.height); |
|---|
| | 108 | |
|---|
| | 109 | uint8_t newly_added_row = cc3_row_counter_calc_ii % CC3_INTEGRAL_IMG_HEIGHT; |
|---|
| | 110 | uint8_t prev_row = (cc3_row_counter_calc_ii - 1 + CC3_INTEGRAL_IMG_HEIGHT) % CC3_INTEGRAL_IMG_HEIGHT; |
|---|
| | 111 | |
|---|
| | 112 | // copy the first pixel |
|---|
| | 113 | cc3_get_pixel(&cc3_img_tmp, 0, 0, &pix_temp); |
|---|
| | 114 | cc3_integral_image[newly_added_row][0] = pix_temp.channel[1]; |
|---|
| | 115 | // cc3_integral_image[newly_added_row][0] = (3*pix_temp.channel[0]+6*pix_temp.channel[1]+pix_temp.channel[2])/10; // rgb->gray |
|---|
| | 116 | fprintf( fp,"%d ",cc3_integral_image[newly_added_row][0] ); |
|---|
| | 117 | |
|---|
| | 118 | // read the row, from next pixel onward and compute cum sum across the row |
|---|
| | 119 | for (uint16_t j = 1; j < cc3_img_tmp.width; j++) |
|---|
| | 120 | { |
|---|
| | 121 | cc3_get_pixel(&cc3_img_tmp, j, 0, &pix_temp); |
|---|
| | 122 | cc3_integral_image[newly_added_row][j] = pix_temp.channel[1]; |
|---|
| | 123 | // cc3_integral_image[newly_added_row][j] = (3*pix_temp.channel[0] + 6*pix_temp.channel[1] + pix_temp.channel[2])/10; |
|---|
| | 124 | fprintf( fp,"%d ",cc3_integral_image[newly_added_row][j] ); |
|---|
| | 125 | |
|---|
| | 126 | // compute cumulative sum across the row |
|---|
| | 127 | cc3_integral_image[newly_added_row][j] += cc3_integral_image[newly_added_row][j-1]; |
|---|
| | 128 | } |
|---|
| | 129 | fprintf( fp, "\n" ); |
|---|
| | 130 | |
|---|
| | 131 | printf("%s %d \n\r", "New Row...", cc3_row_counter_calc_ii); |
|---|
| | 132 | // find cumulative sum along columns to complete the integral image computation |
|---|
| | 133 | for (uint16_t j = 0; j < CC3_INTEGRAL_IMG_WIDTH; j++) |
|---|
| | 134 | { |
|---|
| | 135 | cc3_integral_image[newly_added_row][j]+=cc3_integral_image[prev_row][j]; |
|---|
| | 136 | // printf("%ld ", cc3_integral_image[newly_added_row][j] ); |
|---|
| | 137 | } |
|---|
| | 138 | // printf("\n\r"); |
|---|
| | 139 | |
|---|
| | 140 | } |
|---|
| | 141 | } |
|---|
| | 142 | |
|---|
| | 143 | |
|---|
| | 144 | |
|---|
| | 145 | /* |
|---|
| | 146 | * function to get the feature value for a particular sub-window |
|---|
| | 147 | * |
|---|
| | 148 | */ |
|---|
| | 149 | int16_t cc3_get_feat_val(uint8_t feat_num, uint8_t curr_scale, uint16_t x, uint16_t y) |
|---|
| | 150 | { |
|---|
| | 151 | int32_t fval = 0; |
|---|
| | 152 | uint16_t x_in_ii, y_in_ii; |
|---|
| | 153 | |
|---|
| | 154 | // evaluate the subwindow for this feature |
|---|
| | 155 | for (uint8_t pt=0; pt < 9 ; pt++) |
|---|
| | 156 | { |
|---|
| | 157 | x_in_ii = x + CC3_FACE_FEATURES[feat_num][curr_scale].x[pt]; |
|---|
| | 158 | y_in_ii = (y + CC3_FACE_FEATURES[feat_num][curr_scale].y[pt]) % CC3_INTEGRAL_IMG_HEIGHT; // circular warping |
|---|
| | 159 | fval+=cc3_integral_image[y_in_ii][x_in_ii]*CC3_FACE_FEATURES[feat_num][curr_scale].val_at_corners[pt]; |
|---|
| | 160 | } |
|---|
| | 161 | |
|---|
| | 162 | // taking into account the effect of normalization |
|---|
| | 163 | // printf("%s %d", "fval before std", fval); |
|---|
| | 164 | fval = fval/((int32_t)std); |
|---|
| | 165 | // printf("%s %d", "fval after std", fval); |
|---|
| | 166 | |
|---|
| | 167 | // check if fval < threshold |
|---|
| | 168 | if (fval*CC3_FACE_FEATURES[feat_num][curr_scale].parity < CC3_FACE_FEATURES[feat_num][curr_scale].thresh*CC3_FACE_FEATURES[feat_num][curr_scale].parity) |
|---|
| | 169 | return CC3_FACE_FEATURES[feat_num][curr_scale].alpha; |
|---|
| | 170 | else |
|---|
| | 171 | return 0; |
|---|
| | 172 | } |
|---|
| | 173 | |
|---|
| | 174 | |
|---|
| | 175 | /*-------------- main starts from here---------------*/ |
|---|
| 46 | | |
|---|
| 47 | | // sample showing how to write to the MMC card |
|---|
| 48 | | printf( "Type y to test MMC card, type n if you do not have the card\n" ); |
|---|
| 49 | | c=getchar(); |
|---|
| 50 | | if(c=='y' || c=='Y' ) |
|---|
| 51 | | { |
|---|
| 52 | | printf("\nMMC test...\n"); |
|---|
| 53 | | fp = fopen("c:/test.txt", "w"); |
|---|
| 54 | | fprintf( fp, "This will be written to the MMC...\n" ); |
|---|
| 55 | | fclose(fp); |
|---|
| 56 | | printf( "A string was written to test.txt on the mmc card.\n" ); |
|---|
| 57 | | } |
|---|
| 58 | | |
|---|
| 59 | | // sample showing how to read button |
|---|
| 60 | | printf("push button on camera back to continue\n"); |
|---|
| 61 | | start_time=cc3_timer(); |
|---|
| 62 | | while(!cc3_read_button()); |
|---|
| 63 | | cc3_set_led(1); |
|---|
| 64 | | // sample showing how to use timer |
|---|
| 65 | | printf( "It took you %dms to press the button\n",cc3_timer()-start_time ); |
|---|
| 66 | | |
|---|
| 67 | | |
|---|
| 68 | | |
|---|
| 69 | | // setup an image structure |
|---|
| 70 | | img.channels=3; |
|---|
| 71 | | img.width=cc3_g_current_frame.width; |
|---|
| 72 | | img.height=1; // image will hold just 1 row for scanline processing |
|---|
| 73 | | img.pix = malloc(3 * img.width); // malloc! |
|---|
| 74 | | |
|---|
| 75 | | printf( "Now we will use image data...\n" ); |
|---|
| 76 | | val=0; |
|---|
| 77 | | /* |
|---|
| 78 | | * Track the brightest red spot on the image |
|---|
| 79 | | */ |
|---|
| 80 | | while(1) |
|---|
| 81 | | { |
|---|
| 82 | | uint16_t my_x, my_y; |
|---|
| 83 | | uint8_t max_red; |
|---|
| 84 | | cc3_pixel_t my_pix; |
|---|
| 85 | | max_red=0; |
|---|
| 86 | | my_x=0; |
|---|
| 87 | | my_y=0; |
|---|
| 88 | | |
|---|
| 89 | | if(val&0x1) cc3_set_led(0); else cc3_clr_led(0); |
|---|
| 90 | | if(val&0x2) cc3_set_led(1); else cc3_clr_led(1); |
|---|
| 91 | | if(val&0x3) cc3_set_led(2); else cc3_clr_led(2); |
|---|
| 92 | | if(val&0x4) cc3_set_led(3); else cc3_clr_led(3); |
|---|
| 93 | | val++; |
|---|
| 94 | | |
|---|
| 95 | | // This tells the camera to grab a new frame into the fifo and reset |
|---|
| 96 | | // any internal location information. |
|---|
| 97 | | cc3_pixbuf_load(); |
|---|
| 98 | | for(uint16_t y=0; y<cc3_g_current_frame.height; y++ ) |
|---|
| 99 | | { |
|---|
| 100 | | // FIXME: add cc3_pixbug img read rows |
|---|
| 101 | | // read a row into the image picture memory from the camera |
|---|
| 102 | | cc3_pixbuf_read_rows(img.pix, img.width, 1); |
|---|
| 103 | | for(uint16_t x=0; x<img.width; x++ ) |
|---|
| 104 | | { |
|---|
| 105 | | // get a pixel from the img row memory |
|---|
| 106 | | cc3_get_pixel( &img, x, 0, &my_pix ); |
|---|
| 107 | | if(my_pix.channel[CC3_RED]>max_red) |
|---|
| 108 | | { |
|---|
| 109 | | max_red=my_pix.channel[CC3_RED]; |
|---|
| 110 | | my_x=x; |
|---|
| 111 | | my_y=y; |
|---|
| 112 | | } |
|---|
| 113 | | } |
|---|
| 114 | | |
|---|
| 115 | | } |
|---|
| 116 | | |
|---|
| 117 | | printf( "Found max red value %d at %d, %d\n",max_red,my_x,my_y ); |
|---|
| 118 | | // sample non-blocking serial routine |
|---|
| 119 | | if(!cc3_uart_has_data(0) ) break; |
|---|
| 120 | | } |
|---|
| 121 | | free(img.pix); // don't forget to free! |
|---|
| 122 | | printf( "You pressed %c to escape\n",fgetc(stdin) ); |
|---|
| 123 | | |
|---|
| | 214 | // setup integral image structure |
|---|
| | 215 | cc3_img_tmp.channels=3; // RGB color |
|---|
| | 216 | cc3_img_tmp.width=cc3_g_current_frame.width; // equal to Int_Img_Width |
|---|
| | 217 | cc3_img_tmp.height = 1; // image will hold just 1 row for scanline processing |
|---|
| | 218 | // if ((cc3_img_tmp.pix = malloc(cc3_img_tmp.width*cc3_img_tmp.channels)) == NULL) |
|---|
| | 219 | // printf("Cannot allocate memory \n\r"); // malloc! (to hold one row RGB) |
|---|
| | 220 | cc3_img_tmp.pix = &image_row; |
|---|
| | 221 | |
|---|
| | 222 | if (cc3_img_tmp.width != CC3_INTEGRAL_IMG_WIDTH) |
|---|
| | 223 | printf("Error...image width and integral image width different \n\r"); |
|---|
| | 224 | |
|---|
| | 225 | |
|---|
| | 226 | fp=fopen("c:/test.pgm","w" ); |
|---|
| | 227 | fprintf( fp, "P2\n%d %d\n255\n", cc3_g_current_frame.width, cc3_g_current_frame.height-top_offset-bottom_offset ); |
|---|
| | 228 | |
|---|
| | 229 | while(1) |
|---|
| | 230 | { |
|---|
| | 231 | cc3_num_detected_faces = 0; |
|---|
| | 232 | |
|---|
| | 233 | printf(" New Frame...\n\r"); |
|---|
| | 234 | // This tells the camera to grab a new frame into the fifo and reset |
|---|
| | 235 | // any internal location information. |
|---|
| | 236 | cc3_pixbuf_load(); |
|---|
| | 237 | |
|---|
| | 238 | printf(" captured the image \n\r"); |
|---|
| | 239 | // discard some top rows, given by top_offset |
|---|
| | 240 | for (uint8_t i = 0; i < top_offset ; i++) |
|---|
| | 241 | { |
|---|
| | 242 | cc3_pixbuf_read_rows(cc3_img_tmp.pix, cc3_img_tmp.width, cc3_img_tmp.height); |
|---|
| | 243 | } |
|---|
| | 244 | |
|---|
| | 245 | |
|---|
| | 246 | printf(" read top offset \n\r"); |
|---|
| | 247 | // indicating how many rows have we read in the actual full image |
|---|
| | 248 | // top_offset rows are discarded and next "CC3_INTEGRAL_IMG_HEIGHT" rows are read in the first |
|---|
| | 249 | // instance of the following for loop |
|---|
| | 250 | cc3_row_counter_actual_img = (top_offset-1)+1; // index starts from 0 |
|---|
| | 251 | cc3_row_counter_ii = 0; |
|---|
| | 252 | cc3_row_counter_cropped_img = 0; |
|---|
| | 253 | cc3_row_counter_calc_ii = (CC3_INTEGRAL_IMG_HEIGHT - 1); |
|---|
| | 254 | |
|---|
| | 255 | printf(" reached the main while loop \n\r"); |
|---|
| | 256 | // iterating over the rows of the actual image until the bottom offset |
|---|
| | 257 | while (cc3_row_counter_actual_img < (CC3_IMAGE_HEIGHT - bottom_offset)) |
|---|
| | 258 | { |
|---|
| | 259 | // printf("%s %d \n\r", "CURRENT ROW ",cc3_row_counter_cropped_img); |
|---|
| | 260 | if (cc3_row_counter_calc_ii < CC3_IMAGE_HEIGHT - top_offset - bottom_offset) // check if we need to load any more rows? |
|---|
| | 261 | { |
|---|
| | 262 | // get the current segment and its integral image |
|---|
| | 263 | cc3_get_curr_segment(); |
|---|
| | 264 | } |
|---|
| | 265 | |
|---|
| | 266 | // printf("got the curr seg \n\r"); |
|---|
| | 267 | for (uint8_t curr_scale_idx = 0; curr_scale_idx < CC3_NUM_SCALES; curr_scale_idx++) |
|---|
| | 268 | { |
|---|
| | 269 | |
|---|
| | 270 | // printf (" Current scale %d \n\r", CC3_SCALES[curr_scale_idx]); |
|---|
| | 271 | // check if we need to evaluate subwindows at this scale for this sub-window |
|---|
| | 272 | if (cc3_rows_to_eval_feat[cc3_row_counter_cropped_img][curr_scale_idx] == 1) |
|---|
| | 273 | { |
|---|
| | 274 | // iterate over all horizontal shifted sub-window |
|---|
| | 275 | for (uint8_t curr_pos_x =0; curr_pos_x < CC3_INTEGRAL_IMG_WIDTH - CC3_SCALES[curr_scale_idx]; curr_pos_x+=CC3_WIN_STEPS[curr_scale_idx]) |
|---|
| | 276 | { |
|---|
| | 277 | // printf ("current pos_x %d \n\r",curr_pos_x); |
|---|
| | 278 | // compute the standard deviation for this window |
|---|
| | 279 | x2 = curr_pos_x + CC3_SCALES[curr_scale_idx]-1 ; |
|---|
| | 280 | y2 = (cc3_row_counter_ii + CC3_SCALES[curr_scale_idx]-1) % CC3_INTEGRAL_IMG_HEIGHT; |
|---|
| | 281 | if (x2 >= CC3_INTEGRAL_IMG_WIDTH ) |
|---|
| | 282 | { |
|---|
| | 283 | printf("Error....width outside limits!! \n\r"); |
|---|
| | 284 | } |
|---|
| | 285 | |
|---|
| | 286 | |
|---|
| | 287 | // Don't consider the first row and first column in the sub-window for calculating |
|---|
| | 288 | // std |
|---|
| | 289 | num_pixels = (CC3_SCALES[curr_scale_idx]-1)*(CC3_SCALES[curr_scale_idx]-1); |
|---|
| | 290 | |
|---|
| | 291 | temp1 = cc3_integral_image[cc3_row_counter_ii][curr_pos_x] - cc3_integral_image[cc3_row_counter_ii][x2]; |
|---|
| | 292 | temp2 = cc3_integral_image[y2][x2] - cc3_integral_image[y2][curr_pos_x]; |
|---|
| | 293 | sum_pix = (uint32_t) (temp1 + temp2); |
|---|
| | 294 | mean_val = sum_pix/num_pixels; |
|---|
| | 295 | |
|---|
| | 296 | // printf("%s %u %u %u %u \n\r"," II ", cc3_integral_image[cc3_row_counter_ii+1][curr_pos_x+1], cc3_integral_image[cc3_row_counter_ii+1][x2], cc3_integral_image[y2][curr_pos_x+1], cc3_integral_image[y2][x2]); |
|---|
| | 297 | |
|---|
| | 298 | // printf("%s %d \n\r", "Mean: ", mean_val); |
|---|
| | 299 | // printf("%s %d \n\r", "Num Pixels: ", num_pixels); |
|---|
| | 300 | sum_pix_sq = 0; |
|---|
| | 301 | for (uint8_t i = (cc3_row_counter_ii+1) % CC3_INTEGRAL_IMG_HEIGHT; i != (y2+1)% CC3_INTEGRAL_IMG_HEIGHT; ) |
|---|
| | 302 | { |
|---|
| | 303 | for (uint8_t j = curr_pos_x+1; j <= x2; j++) |
|---|
| | 304 | { |
|---|
| | 305 | temp2 = (i-1+CC3_INTEGRAL_IMG_HEIGHT) % CC3_INTEGRAL_IMG_HEIGHT; |
|---|
| | 306 | temp1 = cc3_integral_image[i][j] - cc3_integral_image[i][j-1]; |
|---|
| | 307 | temp2 = -cc3_integral_image[temp2][j] + cc3_integral_image[temp2][j-1]; |
|---|
| | 308 | temp1 = temp1+temp2; |
|---|
| | 309 | |
|---|
| | 310 | // if (cc3_row_counter_ii == 0) |
|---|
| | 311 | // printf("%s %u \n\r", " ",temp1); |
|---|
| | 312 | |
|---|
| | 313 | sum_pix_sq+=temp1*temp1; |
|---|
| | 314 | } |
|---|
| | 315 | // printf("\n"); |
|---|
| | 316 | i = (i+1) % CC3_INTEGRAL_IMG_HEIGHT; |
|---|
| | 317 | } |
|---|
| | 318 | |
|---|
| | 319 | uint64_t numer, denom; |
|---|
| | 320 | // printf("%s %d %d %d \n\r","current wind ",cc3_row_counter_cropped_img, curr_pos_x, CC3_SCALES[curr_scale_idx]); |
|---|
| | 321 | // printf("%s %u \n\r", "Sum_pix ",sum_pix); |
|---|
| | 322 | // printf("%s %u \n\r", "Square Sum Pix: ",sum_pix_sq); |
|---|
| | 323 | |
|---|
| | 324 | numer = (num_pixels*sum_pix_sq); |
|---|
| | 325 | numer = (numer - sum_pix*sum_pix); |
|---|
| | 326 | // printf("%s %u \n\r", "var: numerator", numer); |
|---|
| | 327 | |
|---|
| | 328 | denom = (num_pixels*num_pixels); |
|---|
| | 329 | // printf("%s %u \n\r", "var: denom", denom); |
|---|
| | 330 | |
|---|
| | 331 | var = numer/denom; //variance |
|---|
| | 332 | // var = (sum_pix_sq/num_pixels) - mean_val*mean_val; |
|---|
| | 333 | // mean_val = sum_pix/num_pixels; |
|---|
| | 334 | |
|---|
| | 335 | // printf("%s %u \n\r", "Var ",var); |
|---|
| | 336 | //printf("%s %u \n\r", "Mean: ", mean_val); |
|---|
| | 337 | |
|---|
| | 338 | if (var < 25) |
|---|
| | 339 | { |
|---|
| | 340 | std = 1; // basically reject the windows with this variance |
|---|
| | 341 | } |
|---|
| | 342 | |
|---|
| | 343 | else |
|---|
| | 344 | { |
|---|
| | 345 | // find the standard deviation |
|---|
| | 346 | for (uint64_t i = 4; i < var/2 ; i++) |
|---|
| | 347 | { |
|---|
| | 348 | if ((i*i <= var) & ((i+1)*(i+1) > var)) |
|---|
| | 349 | { |
|---|
| | 350 | if ((var - i*i) < ((i+1)*(i+1) - var)) |
|---|
| | 351 | std = i; |
|---|
| | 352 | else |
|---|
| | 353 | std = i+1; |
|---|
| | 354 | |
|---|
| | 355 | break; |
|---|
| | 356 | } |
|---|
| | 357 | } |
|---|
| | 358 | } |
|---|
| | 359 | |
|---|
| | 360 | // printf("%s %u \n\r\n", "STD ",std); |
|---|
| | 361 | |
|---|
| | 362 | // std = 5; |
|---|
| | 363 | |
|---|
| | 364 | if ( (std > 4) & (mean_val > 20) & (mean_val < 200)) // check for face only if std > 3, otherwise its too uniform |
|---|
| | 365 | { |
|---|
| | 366 | // printf("%s \n\r\n", "Checking for face "); |
|---|
| | 367 | |
|---|
| | 368 | int16_t feat_sum = 0; |
|---|
| | 369 | // int16_t curr_sum; |
|---|
| | 370 | // compute the val of this sub-window for all the features |
|---|
| | 371 | for (uint8_t curr_feat_idx = 0; curr_feat_idx < CC3_NUM_FEATURES; curr_feat_idx++) |
|---|
| | 372 | { |
|---|
| | 373 | feat_sum+=cc3_get_feat_val(curr_feat_idx, curr_scale_idx, curr_pos_x, cc3_row_counter_ii); |
|---|
| | 374 | // printf("%s %d \n\r", "feat alpha ", curr_sum); |
|---|
| | 375 | // feat_sum+=curr_sum; |
|---|
| | 376 | } |
|---|
| | 377 | |
|---|
| | 378 | // printf("After finding feat val \n\r"); |
|---|
| | 379 | |
|---|
| | 380 | // check if its a face |
|---|
| | 381 | if (feat_sum > CC3_GLOBAL_THRESHOLD) |
|---|
| | 382 | { |
|---|
| | 383 | // printf("Found a face \n\r"); |
|---|
| | 384 | // printf(" global thersh %d \n\r",CC3_GLOBAL_THRESHOLD); |
|---|
| | 385 | // found a face....or the code says so..(and hope so!!!) |
|---|
| | 386 | if (cc3_num_detected_faces < CC3_MAX_FACES ) |
|---|
| | 387 | { |
|---|
| | 388 | // printf(" Face found... %d \n\r", cc3_num_detected_faces); |
|---|
| | 389 | |
|---|
| | 390 | cc3_faces[cc3_num_detected_faces][0] = curr_pos_x; |
|---|
| | 391 | cc3_faces[cc3_num_detected_faces][1] = cc3_row_counter_cropped_img; // + top_offset; |
|---|
| | 392 | cc3_faces[cc3_num_detected_faces][2] = CC3_SCALES[curr_scale_idx]; |
|---|
| | 393 | cc3_num_detected_faces++; |
|---|
| | 394 | } |
|---|
| | 395 | |
|---|
| | 396 | // as of now, if MAX_FACES already reached, do nothing...(for a change, Relax!!) |
|---|
| | 397 | |
|---|
| | 398 | } |
|---|
| | 399 | |
|---|
| | 400 | // printf("end of detecing face \n\r"); |
|---|
| | 401 | } // end of if (std > 5) |
|---|
| | 402 | |
|---|
| | 403 | // printf(" end of iterating over horizintally shisted win \n\r"); |
|---|
| | 404 | } // end of iterating over horizontally shifted sub-windows |
|---|
| | 405 | } |
|---|
| | 406 | |
|---|
| | 407 | // printf(" End of iterating over all scales \n\r"); |
|---|
| | 408 | // printf(" Printing the val of cc3_row_counter_cropped_img %d \n\r",cc3_row_counter_cropped_img); |
|---|
| | 409 | } // end of iterating over all scales |
|---|
| | 410 | |
|---|
| | 411 | // printf("End for curr cropped row %d \n\r", cc3_row_counter_cropped_img); |
|---|
| | 412 | |
|---|
| | 413 | // increment the row counters |
|---|
| | 414 | cc3_row_counter_actual_img++; |
|---|
| | 415 | cc3_row_counter_cropped_img++; |
|---|
| | 416 | cc3_row_counter_ii = (cc3_row_counter_ii + 1) % CC3_INTEGRAL_IMG_HEIGHT; // circular wrapping of integral image row counter |
|---|
| | 417 | cc3_row_counter_calc_ii++; |
|---|
| | 418 | |
|---|
| | 419 | |
|---|
| | 420 | } // end of iterating over all the rows in the actual image (upto bottom_offset) |
|---|
| | 421 | |
|---|
| | 422 | printf("No. of faces : %d \n\r", cc3_num_detected_faces); |
|---|
| | 423 | |
|---|
| | 424 | for (uint8_t i = 0; i < cc3_num_detected_faces; i++) |
|---|
| | 425 | printf ( " Face at x=%d, y=%d scale=%d \n\r",cc3_faces[i][0], cc3_faces[i][1], cc3_faces[i][2]); |
|---|
| | 426 | |
|---|
| | 427 | fclose(fp); |
|---|
| | 428 | // printf(" file closed..."); |
|---|
| | 429 | |
|---|
| | 430 | break; |
|---|
| | 431 | |
|---|
| | 432 | // sample non-blocking serial routine |
|---|
| | 433 | if(!cc3_uart_has_data(0) ) break; |
|---|
| | 434 | } // end of while |
|---|
| | 435 | |
|---|
| | 436 | |
|---|
| | 437 | |
|---|
| | 438 | free(cc3_img_tmp.pix); // don't forget to free! |
|---|
| | 439 | printf( "You pressed %c to escape \n\r",fgetc(stdin) ); |
|---|
| | 440 | |
|---|