void histogram_process(){ static unsigned char *img; int i, hi, c; int y, v, u; static int x, img_offset; static int viewport_size; unsigned int histo_fill[5]; switch (histogram_stage) { case 0: img=((mode_get()&MODE_MASK) == MODE_PLAY)?vid_get_viewport_fb_d():((kbd_is_key_pressed(KEY_SHOOT_HALF))?vid_get_viewport_fb():vid_get_viewport_live_fb()); if (img==NULL){ img = vid_get_viewport_fb(); } img_offset = vid_get_viewport_image_offset(); // offset into viewport for when image size != viewport size (e.g. 16:9 image on 4:3 LCD) viewport_size = vid_get_viewport_height() * vid_get_viewport_buffer_width(); for (c=0; c<5; ++c) { for (i=0; i<HISTO_WIDTH; ++i) { histogram_proc[c][i]=0; } histo_max[c] = histo_max_center[c] = 0; } histogram_stage=1; break; case 1: case 2: case 3: x = 0; int l = 11; for (i=(histogram_stage-1)*6; i<viewport_size*3; i+=6*3*2) { y = img[img_offset+i+1]; u = *(signed char*)(&img[img_offset+i]); if (u&0x00000080) u|=0xFFFFFF00; v = *(signed char*)(&img[img_offset+i+2]); if (v&0x00000080) v|=0xFFFFFF00; hi = y*HISTO_WIDTH/256; // Y ++histogram_proc[HISTO_Y][hi]; hi = clip(((y<<12) + v*5743 + 2048)/4096)*HISTO_WIDTH/256; // R ++histogram_proc[HISTO_R][hi]; hi = clip(((y<<12) - u*1411 - v*2925 + 2048)/4096)*HISTO_WIDTH/256; // G ++histogram_proc[HISTO_G][hi]; hi = clip(((y<<12) + u*7258 + 2048)/4096)*HISTO_WIDTH/256; // B ++histogram_proc[HISTO_B][hi]; // Handle case where viewport memory buffer is wider than the actual buffer. x++; if (x == vid_get_viewport_width()) { i += vid_get_viewport_row_offset(); x = 0; } } ++histogram_stage; break;
UYVyyyAs i understand your text correct the 3 yyy values are not count.To make it more precise to overexpose, there can check for highest Y value and only the highest value is calc with u and v
histogram_stage 1 xxx xxx 2 xxx xxx 3 xxx xxxviewport data -> UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY UYVYYY
Can you please check, if your propset 4 Camera have on prop value 200 a overexpose Value show ?My Ixus 1000 use propset 4 and show on prop 200 a value, that seem show how many pixels are overexpose.
The G12 has this prop 200 value which does appear to relate to the image brightness; but I can't say if it would be of any use for determining overexposure. As you say it does not get updated when you press the shutter, it only appears to be set when the live view is displayed. You may need to find where the property is set or used in the firmware to work out its function.
void histogram_process(){ static unsigned char *img; register int i, c, col, row; int hi; int y, v, u; int triplets_in_bytes; static int row_offset, col_offset, buffer_width; static int viewport_width; static int viewport_height; unsigned int histo_fill[5]; switch (histogram_stage) { case 0: img=((mode_get()&MODE_MASK) == MODE_PLAY)?vid_get_viewport_fb_d():((kbd_is_key_pressed(KEY_SHOOT_HALF))?vid_get_viewport_fb():vid_get_viewport_live_fb()); if (img==NULL){ img = vid_get_viewport_fb(); } buffer_width = vid_get_viewport_buffer_width ( ); // upon camera viewport buffer, in triplets row_offset = vid_get_viewport_yoffset ( ); // upon camera aspect ratio, in row col_offset = vid_get_viewport_xoffset ( ); // upon camera aspect ratio, in triplets viewport_height = vid_get_viewport_height(); // in row viewport_width = vid_get_viewport_width(); // in triplets for (c=5; c--; ) { for (i=HISTO_WIDTH; i--; ) { histogram_proc[c][i]=0; } histo_max[c] = histo_max_center[c] = 0; } histogram_stage=1; break; case 1: case 2: case 3: case 4: case 5: case 6: // for each viewport row for ( row = viewport_height; row--; ) { // for each viewport column, interlaced upon histogram_stage, in triplets for ( col = ( histogram_stage-1 ); col < viewport_width; col += ( 6 * 2 ) ) { triplets_in_bytes = 3 // numbers of bytes per triplets * ( buffer_width // memory buffer containing viewport triplets and more, upon camera * ( row_offset // empty rows, at the top the buffer, upon aspect ratio + row ) + ( col_offset // empty columns, at the left of the buffer, upon aspect ratio + col ) ); y = img [ triplets_in_bytes + 1 ]; u = * ( signed char * ) ( &img [ triplets_in_bytes ] ); if ( u & 0x00000080 ) u |= 0xFFFFFF00; v = * ( signed char * ) ( &img [ triplets_in_bytes + 2 ] ); if ( v & 0x00000080 ) v |= 0xFFFFFF00; hi = ( y * HISTO_WIDTH ) >> 8; // Y ++histogram_proc [ HISTO_Y ] [ hi ]; hi = ( clip ( ( ( y << 12 ) + v * 5742 + 2048 ) >> 12 ) * HISTO_WIDTH ) >> 8; // R ++histogram_proc [ HISTO_R ] [ hi ]; hi = ( clip ( ( ( y << 12 ) - ( u * 1410 + v * 2925 ) + 2048 ) >> 12 ) * HISTO_WIDTH ) >> 8; // G ++histogram_proc [ HISTO_G ] [ hi ]; hi = ( clip ( ( ( y << 12 ) + u * 7258 + 2048 ) >> 12 ) * HISTO_WIDTH ) >> 8; // B ++histogram_proc [ HISTO_B ] [ hi ]; } ; } ; ++histogram_stage; break; case 7: for (i=HISTO_WIDTH; i--; ) { // G histogram_proc[HISTO_RGB][i]=histogram_proc[HISTO_R][i]+histogram_proc[HISTO_G][i]+histogram_proc[HISTO_B][i]; } for (c=5; c--; ) { // calculate maximums for (i=HISTO_WIDTH; i--; ) { if (histo_max[c]<histogram_proc[c][i]) histo_max[c]=histogram_proc[c][i]; if (histo_max_center[c]<histogram_proc[c][i] && i>=conf.histo_ignore_boundary && i<HISTO_WIDTH-conf.histo_ignore_boundary) histo_max_center[c]=histogram_proc[c][i]; } if (histo_max[c] > 0) { histo_max_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max[c]); } else { histo_max_invw[c] = 0.0f; } if (histo_max_center[c] > 0) { histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max_center[c]); } else { histo_max_center_invw[c] = 0.0f; } } if (histo_max[HISTO_RGB] > 0) { // over- / under- expos under_exposed = ((histogram_proc[HISTO_RGB][0]<<3) +(histogram_proc[HISTO_RGB][1]<<2) +histogram_proc[HISTO_RGB][2]) > exposition_thresh; over_exposed = (histogram_proc[HISTO_RGB][HISTO_WIDTH-3] +(histogram_proc[HISTO_RGB][HISTO_WIDTH-2]<<2) +(histogram_proc[HISTO_RGB][HISTO_WIDTH-1]<<3)) > exposition_thresh; } else { over_exposed = 0; under_exposed = 1; } histogram_stage=8; state_expos_recalculated = 1; break; case 8: for (c=5; c--; ) { histo_fill[c]=0; for (i=HISTO_WIDTH; i--; ) { histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c]; if (histogram[c][i] > HISTO_HEIGHT) histogram[c][i] = HISTO_HEIGHT; histo_fill[c]+=histogram[c][i]; } } if (conf.histo_auto_ajust) { histo_magnification = histo_fill[histo_main]*1000/(HISTO_HEIGHT*HISTO_WIDTH); if (histo_magnification<200) { // try to ajust if average level is less than 20% histo_magnification=200*1000/histo_magnification; for (c=5; c--; ) { for (i=HISTO_WIDTH;i--; ) { histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c]*histo_magnification/1000; if (histogram[c][i] > HISTO_HEIGHT) histogram[c][i] = HISTO_HEIGHT; } } } else histo_magnification=0; } else { histo_magnification=0; } histogram_stage=0; break; case HISTOGRAM_IDLE_STAGE: break; }}
Started by hiker_jon « 1 2 3 » General Discussion and Assistance
Started by hiker_jon General Discussion and Assistance
Started by zcream General Help and Assistance on using CHDK stable releases
Started by pigeonhill General Help and Assistance on using CHDK stable releases