From 72c0789ec54611e88fc49bb32e682395f8b1450b Mon Sep 17 00:00:00 2001 From: Niels Elburg Date: Sun, 22 Jul 2007 09:43:11 +0000 Subject: [PATCH] work in progress git-svn-id: svn://code.dyne.org/veejay/trunk@1000 eb8d1916-c9e9-0310-b8de-cf0c9472ead5 --- .../veejay-server/libvje/effects/common.c | 61 +++--- .../veejay-server/libvje/effects/common.h | 3 +- .../veejay-server/libvje/effects/texmap.c | 182 ++++++++++++++---- .../veejay-server/libvje/effects/texmap.h | 2 +- veejay-1.0/veejay-server/libvje/internal.h | 2 +- veejay-1.0/veejay-server/libvje/vj-effman.c | 2 +- 6 files changed, 186 insertions(+), 66 deletions(-) diff --git a/veejay-1.0/veejay-server/libvje/effects/common.c b/veejay-1.0/veejay-server/libvje/effects/common.c index d14601d5..d73ab35c 100644 --- a/veejay-1.0/veejay-server/libvje/effects/common.c +++ b/veejay-1.0/veejay-server/libvje/effects/common.c @@ -1688,6 +1688,8 @@ void veejay_histogram_analyze( void *his, VJFrame *f, int type ) #define MAX(a,b) ( (a)>(b) ? (a) : (b) ) #endif +#define max4(a,b,c,d) MAX(MAX(MAX(a,b),c),d) + void veejay_distance_transform( uint32_t *plane, int w, int h, uint32_t *output) { register unsigned int x,y; @@ -1756,8 +1758,10 @@ uint32_t veejay_component_labeling(int w, int h, uint32_t *I , uint32_t *M) I[ y * w + x ] = p1; } else { - Mi = MIN( p1,p2 ); - Ma = MAX( p1,p2 ); + // Mi = min4(p1,p2,p3,p4); + // Ma = max4(p1,p2,p3,p4); + //Mi = MIN( p1,p2 ); + //Ma = MAX( p1,p2 ); I[ y * w + x ] = Mi; @@ -1812,7 +1816,7 @@ static inline int center_of_blob( int width, int height, uint8_t label, - uint32_t *dx, uint32_t *dy) + uint32_t *dx, uint32_t *dy, uint32_t *xsize, uint32_t *ysize) { unsigned int i,j; uint32_t product_row = 0; @@ -1830,6 +1834,8 @@ static inline int center_of_blob( if ( img[i * width + j] == label ) pixels_row++; } + if( pixels_row > *(xsize) ) + *xsize = pixels_row; product_row += (i * pixels_row); pixels_row_c += pixels_row; } @@ -1842,26 +1848,15 @@ static inline int center_of_blob( if( img[i * width + j ] == label ) pixels_col ++; } + if( pixels_col > *(ysize) ) + *ysize = pixels_col; product_col += (j * pixels_col); product_col_c += pixels_col; } - /*for( i = 0; i < height; i ++ ) - { - pixels_col = 0; - for( j = 0; j < width; j ++ ) - { - if ( img[i * width + j] == label ) - pixels_col ++; - } - product_col += (i * pixels_col); - product_col_c += pixels_col; - }*/ if( pixels_row_c == 0 || product_col_c == 0 ) - { return 0; - } *dy = ( product_row / pixels_row_c ); *dx = ( product_col / product_col_c ); @@ -1876,7 +1871,10 @@ int compare_l8( const void *a, const void *b ) uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, uint32_t *XX, - uint32_t *YY) + uint32_t *YY, + uint32_t *xsize, + uint32_t *ysize, + int min_blob_weight) { uint8_t label = 0; uint32_t x,y,i; @@ -1886,6 +1884,8 @@ uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, uint8_t n_labels = 0; + veejay_memset( Eq, 0, sizeof(Eq) ); + for( y = 1; y < (h-1); y ++ ) { for ( x = 1; x < (w-1); x ++ ) @@ -1894,21 +1894,23 @@ uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, { p1 = I[ (y-1) * w + x ]; p2 = I[ y * w + (x-1) ]; - + if( p1 == 0 && p2 == 0 ) { label++; - if( label > 0xff ) + if( label > 254 ) + { + veejay_msg(0, "available labels exceeded"); return 0; - + } I[ y * w + x ] = Eq[ label ] = label; - } else if ( p1 == 0 ) { + } else if ( p1 == 0) { I[ y * w + x ] = p2; } else if ( p2 == 0 ) { I[ y * w + x ] = p1; } else if ( p1 == p2 ) { I[ y * w + x ] = p1; - } else { + } else { Mi = MIN( p1,p2 ); Ma = MAX( p1,p2 ); @@ -1940,12 +1942,12 @@ uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, } } - if( n_labels > 255 ) + if( n_labels > 254 ) { veejay_msg(0, "Too many blobs"); return 0; } - for( i = 0; i < n_labels ; i ++ ) + for( i = 0; i <= n_labels ; i ++ ) M[ i ] = 0; for( y = 0; y < h ; y ++ ) @@ -1961,13 +1963,18 @@ uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, } if( n_labels <= 0 ) - { return 0; - } for( i = 1; i <= n_labels; i ++ ) { - if(! center_of_blob( I,w,h, i, &(XX[i]), &(YY[i]) ) ) + if( (M[i] * 8) >= min_blob_weight ) + { + if(! center_of_blob( I,w,h, i, &(XX[i]), &(YY[i]), &(xsize[i]), &(ysize[i]) ) ) + { + M[i] = 0; + } + } + else { M[i] = 0; } diff --git a/veejay-1.0/veejay-server/libvje/effects/common.h b/veejay-1.0/veejay-server/libvje/effects/common.h index 8bbc34ee..a9e95855 100644 --- a/veejay-1.0/veejay-server/libvje/effects/common.h +++ b/veejay-1.0/veejay-server/libvje/effects/common.h @@ -313,5 +313,6 @@ void veejay_histogram_draw_rgb( void *his, VJFrame *f, uint8_t *rgb, int in, int void veejay_distance_transform( uint32_t *plane, int w, int h, uint32_t *output); -uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, uint32_t *XX, uint32_t *YY); +uint8_t veejay_component_labeling_8(int w, int h, uint8_t *I , uint32_t *M, uint32_t *XX, uint32_t *YY, + uint32_t *xsize, uint32_t *ysize, int blob); diff --git a/veejay-1.0/veejay-server/libvje/effects/texmap.c b/veejay-1.0/veejay-server/libvje/effects/texmap.c index d6f22a35..e4481472 100644 --- a/veejay-1.0/veejay-server/libvje/effects/texmap.c +++ b/veejay-1.0/veejay-server/libvje/effects/texmap.c @@ -38,6 +38,9 @@ static sws_template template_; static VJFrame to_shrink_; static VJFrame shrinked_; static int dw_, dh_; +static int x_[255]; +static int y_[255]; +static void *proj_[255]; typedef struct { @@ -46,11 +49,21 @@ typedef struct uint8_t *current; } texmap_data; +#define ANIMAX + +#ifdef ANIMAX +#define ANIMAX_GROUP "224.0.0.17" +#define ANIMAX_PORT 1234 +#include +#endif + +static void *sender_ = NULL; + vj_effect *texmap_init(int width, int height) { //int i,j; vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect)); - ve->num_params = 5; + ve->num_params = 6; ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */ ve->limits[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */ ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */ @@ -59,23 +72,29 @@ vj_effect *texmap_init(int width, int height) ve->limits[0][1] = 0; /* reverse */ ve->limits[1][1] = 1; ve->limits[0][2] = 0; /* show mask */ - ve->limits[1][2] = 3; + ve->limits[1][2] = 4; ve->limits[0][3] = 0; /* switch to take bg mask */ ve->limits[1][3] = 1; ve->limits[0][4] = 1; /* thinning */ ve->limits[1][4] = 100; - + ve->limits[0][5] = 1; /* minimum blob weight */ + ve->limits[1][5] = 5000; + ve->defaults[0] = 30; ve->defaults[1] = 0; ve->defaults[2] = 2; ve->defaults[3] = 0; ve->defaults[4] = 5; - + ve->defaults[5] = 200; + ve->description = "Map B to A (sub bg, texture map))"; ve->extra_frame = 1; ve->sub_format = 1; ve->has_user = 1; ve->user_data = NULL; +#ifdef ANIMAX + sender_ = mcast_new_sender( ANIMAX_GROUP ); +#endif return ve; } @@ -117,7 +136,8 @@ int texmap_malloc(void **d, int width, int height) dt_map = (uint32_t*) vj_calloc( ru8(width * height * sizeof(uint32_t) + width ) ); veejay_memset( &template_, 0, sizeof(sws_template) ); - + veejay_memset( proj_, 0, sizeof(proj_) ); + template_.flags = 1; vj_get_yuvgrey_template( &to_shrink_, width, height ); @@ -130,6 +150,9 @@ int texmap_malloc(void **d, int width, int height) yuv_sws_get_cpu_flags() ); + veejay_memset( x_, 0, sizeof(x_) ); + veejay_memset( y_, 0, sizeof(y_) ); + return 1; } @@ -150,6 +173,11 @@ void texmap_free(void *d) shrink_ = NULL; } + int i; + for( i = 0; i < 255; i++ ) + if( proj_[i] ) + viewport_destroy( proj_[i] ); + d = NULL; } @@ -176,9 +204,6 @@ void texmap_prepare(void *user, uint8_t *map[3], int width, int height) static void binarify( uint8_t *bm, uint32_t *dst, uint8_t *bg, uint8_t *src,int threshold,int reverse, const int len ) { int i; - - - if(!reverse) { for( i = 0; i < len; i ++ ) @@ -186,7 +211,7 @@ static void binarify( uint8_t *bm, uint32_t *dst, uint8_t *bg, uint8_t *src,int if ( abs(bg[i] - src[i]) <= threshold ) { dst[i] = 0; bm[i] = 0; } else - { dst[i] = 1; bm[i] = 1; } + { dst[i] = 1; bm[i] = 0xff; } } } @@ -197,7 +222,7 @@ static void binarify( uint8_t *bm, uint32_t *dst, uint8_t *bg, uint8_t *src,int if ( abs(bg[i] - src[i]) >= threshold ) { dst[i] = 0; bm[i] = 0; } else - { dst[i] = 1; bm[i] = 1; } + { dst[i] = 1; bm[i] = 0xff; } } } @@ -208,9 +233,11 @@ static void texmap_centroid() } +static int bg_frame_ = 0; + void texmap_apply(void *ed, VJFrame *frame, VJFrame *frame2, int width, int height, - int threshold, int reverse,int mode, int take_bg, int feather) + int threshold, int reverse,int mode, int take_bg, int feather, int min_blob_weight) { unsigned int i; @@ -224,22 +251,42 @@ void texmap_apply(void *ed, VJFrame *frame, 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)); + texmap_data *ud = (texmap_data*) ed; if( take_bg != take_bg_ ) { veejay_memcpy( static_bg, frame->data[0], frame->len ); - VJFrame tmp; + /* VJFrame tmp; veejay_memset( &tmp, 0, sizeof(VJFrame)); tmp.data[0] = static_bg; tmp.width = width; tmp.height = height; softblur_apply( &tmp, width,height,0); + */ 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; } @@ -251,6 +298,26 @@ void texmap_apply(void *ed, VJFrame *frame, //@ calculate distance map veejay_distance_transform( ud->data, width, height, dt_map ); +#ifdef ANIMAX + uint32_t x,y,k=2; + uint32_t *coord = vj_calloc( sizeof(uint32_t) * len); + coord[0] = width; + coord[1] = height; + for( y =0 ; y < height; y ++ ) + { + for( x =0 ; x < width; x++ ) + { + if( dt_map[ y * width + x ] == 1 ) + { + coord[k] = x; + coord[k+1] = y; + k+=2; + } + } + } + mcast_send( sender_, coord, k * sizeof(uint32_t), ANIMAX_PORT); + free(coord); +#endif if(mode==1) { @@ -302,42 +369,87 @@ void texmap_apply(void *ed, VJFrame *frame, to_shrink_.data[0] = ud->bitmap; shrinked_.data[0] = ud->current; - uint8_t blobs[255]; + 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_, ud->current, blobs, cx,cy ); + uint32_t labels = veejay_component_labeling_8(dw_,dh_, shrinked_.data[0], blobs, cx,cy,xsize,ysize, + min_blob_weight); - for( i = 1; i <= labels ; i ++ ) + if(mode == 4 ) { - if( blobs[i] ) + veejay_memcpy( Y, ud->bitmap, len ); + veejay_memset( Cb, 128, len ); + veejay_memset( Cr, 128, len ); + } + else + { + veejay_memset( Y, 0 , len ); + veejay_memset( Cb, 128, len ); + veejay_memset( Cr, 128, len ); + } + + for( i = 1; i <= labels; i ++ ) + { + if( blobs[i] > 0 ) { - int radius = (int) ( 0.5 + sqrt( (double) 8.0 * blobs[i]) ); - cx[i] = cx[i] * 8; - cy[i] = cy[i] * 8; - viewport_line( Y, cx[i] - radius, cy[i] - radius , - cx[i] + radius, cy[i] - radius , - width, height, 128 ); + int radius = (int) ( 0.5 + sqrt( sw * blobs[i]) ); + int nx = cx[i] * sx; + int ny = cy[i] * sy; + int size_x = xsize[i] * sx; + int size_y = ysize[i] * sy * 0.5; // over size in x axis + + if( mode != 4 && ( abs( nx - x_[i] ) > 10 || abs( ny - y_[i] ) > 10 ) ) + //if( mode!=4 && cx[i] != x_[i] || cy[i] != y_[i] || !proj_[i]) + { + x_[i] = nx; + y_[i] = ny; - viewport_line( Y, cx[i] - radius, cy[i] - radius , - cx[i] - radius, cy[i] + radius , - width, height, 128 ); + if(proj_[i]) + viewport_destroy( proj_[i] ); + proj_[i] = viewport_fx_init_map( width,height, + nx - size_x, + ny - size_y, + nx + size_x, + ny - size_y, + nx + size_x, + ny + size_y, + nx - size_x, + ny + size_y ); + if(!proj_[i]) + return; + } - viewport_line( Y, cx[i] + radius, cy[i] - radius , - cx[i] + radius, cy[i] + radius , - width, height, 128 ); + if( mode == 4 ) + { + viewport_line( Y, nx - size_x, ny - size_y , + nx + size_x, ny - size_y , + width, height, 0xff ); - viewport_line( Y, cx[i] - radius, cy[i] + radius, - cx[i] + radius, cy[i] + radius , - width, height, 128 ); -// veejay_msg( 0, "B %d: %dx%d, weight: %d, pos %d x %d", -// i, dw_, dh_, blobs[i], cx[i],cy[i]); + viewport_line( Y, nx - size_x, ny - size_y , + nx - size_x, ny + size_y , + width, height, 0xff ); + + viewport_line( Y, nx + size_x, ny - size_y , + nx + size_x, ny + size_y , + width, height, 0xff ); + + viewport_line( Y, nx - size_x, ny + size_y, + nx + size_x, ny + size_y , + width, height, 128 ); + } + else + { + viewport_process_dynamic_map( proj_[i], frame2->data, frame->data, dt_map, feather ); + } } } + + } diff --git a/veejay-1.0/veejay-server/libvje/effects/texmap.h b/veejay-1.0/veejay-server/libvje/effects/texmap.h index 0210ba66..d6b430cb 100644 --- a/veejay-1.0/veejay-server/libvje/effects/texmap.h +++ b/veejay-1.0/veejay-server/libvje/effects/texmap.h @@ -30,6 +30,6 @@ int texmap_malloc(void **c, int w, int h); void texmap_prepare(void *d, uint8_t *map[3], int w, int h); void texmap_apply(void *d , VJFrame *frame, VJFrame *frame2, int width, int height, - int th, int reverse, int show, int take, int feather); + int th, int reverse, int show, int take, int feather, int blob); void texmap_destroy(); #endif diff --git a/veejay-1.0/veejay-server/libvje/internal.h b/veejay-1.0/veejay-server/libvje/internal.h index f4e89449..d1cb35cf 100644 --- a/veejay-1.0/veejay-server/libvje/internal.h +++ b/veejay-1.0/veejay-server/libvje/internal.h @@ -370,7 +370,7 @@ extern void whiteframe_apply(VJFrame *frame, VJFrame *frame2, extern void texmap_apply(void *dd, VJFrame *frame, VJFrame *frame2, int width, int height, - int mode, int threshold, int c , int take, int feather); + int mode, int threshold, int c , int take, int feather, int blob); extern void diff_apply(void *dd, VJFrame *frame, VJFrame *frame2, int width, int height, diff --git a/veejay-1.0/veejay-server/libvje/vj-effman.c b/veejay-1.0/veejay-server/libvje/vj-effman.c index f67cdf50..36d1ba59 100644 --- a/veejay-1.0/veejay-server/libvje/vj-effman.c +++ b/veejay-1.0/veejay-server/libvje/vj-effman.c @@ -460,7 +460,7 @@ void vj_effman_apply_video_effect( VJFrame **frames, VJFrameInfo *frameinfo ,vjp break; case VJ_VIDEO_EFFECT_TEXMAP: texmap_apply( vj_effects[entry]->user_data, frames[0],frames[1], - frameinfo->width,frameinfo->height,arg[0],arg[1],arg[2],arg[3],arg[4] ); + frameinfo->width,frameinfo->height,arg[0],arg[1],arg[2],arg[3],arg[4],arg[5] ); break; case VJ_VIDEO_EFFECT_WHITEFRAME: whiteframe_apply(frames[0], frames[1], frameinfo->width, frameinfo->height);