void contourextract_apply(void *ed, VJFrame *frame,int width, int height, int threshold, int reverse,int mode, int take_bg, int feather, int min_blob_weight) { unsigned int i,j,k; const uint32_t len = frame->len; const uint32_t uv_len = frame->uv_len; uint8_t *Y = frame->data[0]; uint8_t *Cb = frame->data[1]; uint8_t *Cr = frame->data[2]; uint32_t cx[256]; uint32_t cy[256]; uint32_t xsize[256]; uint32_t ysize[256]; float sx = (float) width / (float) dw_; float sy = (float) height / (float) dh_; float sw = (float) sqrt( sx * sy ); veejay_memset( cx,0,sizeof(cx)); veejay_memset( cy,0,sizeof(cy)); veejay_memset( xsize,0,sizeof(xsize)); veejay_memset( ysize,0,sizeof(ysize)); contourextract_data *ud = (contourextract_data*) ed; if( take_bg != take_bg_ ) { vj_frame_copy1( frame->data[0], static_bg, frame->len ); take_bg_ = take_bg; bg_frame_ ++; return; } if( bg_frame_ > 0 && bg_frame_ < 4 ) { for( i = 0 ; i < len ; i ++ ) { static_bg[i] = (static_bg[i] + Y[i] ) >> 1; } bg_frame_ ++; return; } int packets = 0; //@ clear distance transform map veejay_memset( dt_map, 0 , len * sizeof(uint32_t) ); //@ todo: optimize with mmx binarify( ud->bitmap,static_bg, frame->data[0], threshold, reverse,len ); if(mode==1) { //@ show difference image in grayscale vj_frame_copy1( ud->bitmap, Y, len ); vj_frame_clear1( Cb, 128, uv_len ); vj_frame_clear1( Cr, 128, uv_len ); return; } //@ calculate distance map veejay_distance_transform8( ud->bitmap, width, height, dt_map ); to_shrink_.data[0] = ud->bitmap; shrinked_.data[0] = ud->current; uint32_t blobs[255]; veejay_memset( blobs, 0, sizeof(blobs) ); yuv_convert_and_scale_grey( shrink_, &to_shrink_, &shrinked_ ); uint32_t labels = veejay_component_labeling_8(dw_,dh_, shrinked_.data[0], blobs, cx,cy,xsize,ysize, min_blob_weight); veejay_memset( Y, 0, len ); veejay_memset( Cb , 128, uv_len); veejay_memset( Cr , 128, uv_len ); int num_objects = 0; for( i = 1 ; i <= labels; i ++ ) if( blobs[i] ) num_objects ++; //@ Iterate over blob's bounding boxes and extract contours for( i = 1; i <= labels; i ++ ) { if( blobs[i] > 0 ) { int nx = cx[i] * sx; int ny = cy[i] * sy; int size_x = xsize[i] * sx; int size_y = ysize[i] * sy * 0.5; int x1 = nx - size_x; int y1 = ny - size_y; int x2 = nx + size_y; int y2 = ny + size_y; int n_points = 0; int center = 0; int dx1 = 0,dy1=0; if( x1 < 0 ) x1 = 0; else if ( x1 > width ) x1 = width; if( x2 < 0 ) x2 = 0; else if ( x2 > width ) x2 = width; if( y1 < 0 ) y1 = 0; else if ( y1 >= height ) y1 = height -1; if( y2 < 0 ) y2 = 0; else if ( y2 >= height ) y2 = height -1; for( k = y1; k < y2; k ++ ) { for( j = x1; j < x2; j ++ ) { //@ use distance transform map to find centroid (fuzzy) if( dt_map[ (k * width + j) ] > center ) { center = dt_map[ (k* width +j) ]; dx1 = j; dy1 = k; } if( dt_map[ (k * width + j) ] == feather ) { Y[ (k * width +j)] = 0xff; points[ n_points ]->x = j; points[ n_points ]->y = k; n_points++; if( n_points >= 11999 ) { veejay_msg(0, "Too many points in contour"); return; } } } } } } }
void contourextract_apply(void *ed, VJFrame *frame, int threshold, int reverse, int mode, int take_bg, int feather, int min_blob_weight) { unsigned int i; const unsigned int width = frame->width; const unsigned int height = frame->height; const int len = frame->len; const int uv_len = frame->uv_len; uint8_t *Y = frame->data[0]; uint8_t *Cb = frame->data[1]; uint8_t *Cr = frame->data[2]; uint32_t cx[256]; uint32_t cy[256]; uint32_t xsize[256]; uint32_t ysize[256]; uint32_t blobs[255]; veejay_memset( cx,0,sizeof(cx)); veejay_memset( cy,0,sizeof(cy)); veejay_memset( xsize,0,sizeof(xsize)); veejay_memset( ysize,0,sizeof(ysize)); veejay_memset( blobs, 0, sizeof(blobs) ); contourextract_data *ud = (contourextract_data*) ed; //@ clear distance transform map veejay_memset( dt_map, 0 , len * sizeof(uint32_t) ); binarify_1src( ud->bitmap, frame->data[0], threshold, reverse, width, height ); if(mode==1) { //@ show difference image in grayscale vj_frame_copy1( ud->bitmap, Y, len ); vj_frame_clear1( Cb, 128, uv_len ); vj_frame_clear1( Cr, 128, uv_len ); return; } //@ calculate distance map veejay_distance_transform8( ud->bitmap, width, height, dt_map ); to_shrink_.data[0] = ud->bitmap; shrinked_.data[0] = ud->current; yuv_convert_and_scale_grey( shrink_, &to_shrink_, &shrinked_ ); uint32_t labels = veejay_component_labeling_8(dw_,dh_, shrinked_.data[0], blobs, cx,cy,xsize,ysize,min_blob_weight); veejay_memset( Y, 0, len ); veejay_memset( Cb , 128, uv_len); veejay_memset( Cr , 128, uv_len ); int num_objects = 0; for( i = 1 ; i <= labels; i ++ ) if( blobs[i] ) num_objects ++; //@ Iterate over blob's bounding boxes and extract contours //@ use snippet below to get center of blob --> parameter extraction TODO /* for( i = 1; i <= labels; i ++ ) { if( blobs[i] > 0 ) { int nx = cx[i] * sx; int ny = cy[i] * sy; int size_x = xsize[i] * sx; int size_y = ysize[i] * sy * 0.5; int x1 = nx - size_x; int y1 = ny - size_y; int x2 = nx + size_y; int y2 = ny + size_y; int n_points = 0; int center = 0; if( x1 < 0 ) x1 = 0; else if ( x1 > width ) x1 = width; if( x2 < 0 ) x2 = 0; else if ( x2 > width ) x2 = width; if( y1 < 0 ) y1 = 0; else if ( y1 >= height ) y1 = height -1; if( y2 < 0 ) y2 = 0; else if ( y2 >= height ) y2 = height -1; for( k = y1; k < y2; k ++ ) { for( j = x1; j < x2; j ++ ) { //@ use distance transform map to find centroid (fuzzy) if( dt_map[ (k * width + j) ] > center ) { center = dt_map[ (k* width +j) ]; } if( dt_map[ (k * width + j) ] == feather ) { Y[ (k * width +j)] = 0xff; points[ n_points ]->x = j; points[ n_points ]->y = k; n_points++; if( n_points >= 11999 ) { veejay_msg(0, "Too many points in contour"); return; } } } } } } */ }