📄 distort.c
字号:
GaussianConvolution( p_inpic, p_smooth ); /* Sobel gradient | -1 0 1 | | 1 2 1 | | -2 0 2 | and | 0 0 0 | | -1 0 1 | | -1 -2 -1 | */ for( y = 1; y < i_num_lines - 1; y++ ) { for( x = 1; x < i_src_visible - 1; x++ ) { int gradx = ( ( p_smooth[(y-1)*i_src_visible+x] - p_smooth[(y+1)*i_src_visible+x] ) <<1 ) + ( p_smooth[(y-1)*i_src_visible+x-1] - p_smooth[(y+1)*i_src_visible+x-1] ) + ( p_smooth[(y-1)*i_src_visible+x+1] - p_smooth[(y+1)*i_src_visible+x+1] ); int grady = ( ( p_smooth[y*i_src_visible+x-1] - p_smooth[y*i_src_visible+x+1] ) <<1 ) + ( p_smooth[(y-1)*i_src_visible+x-1] - p_smooth[(y-1)*i_src_visible+x+1] ) + ( p_smooth[(y+1)*i_src_visible+x-1] - p_smooth[(y+1)*i_src_visible+x+1] ); p_grad[y*i_src_visible+x] = (uint32_t)(abs( gradx ) + abs( grady )); /* tan( 22.5 ) = 0,414213562 .. * 128 = 53 * tan( 26,565051177 ) = 0.5 * tan( 45 + 22.5 ) = 2,414213562 .. * 128 = 309 * tan( 63,434948823 ) 2 */ if( (grady<<1) > gradx ) p_theta[y*i_src_visible+x] = THETA_P; else if( (grady<<1) < -gradx ) p_theta[y*i_src_visible+x] = THETA_M; else if( !gradx || abs(grady) > abs(gradx)<<1 ) p_theta[y*i_src_visible+x] = THETA_Y; else p_theta[y*i_src_visible+x] = THETA_X; } } /* edge computing */ for( y = 1; y < i_num_lines - 1; y++ ) { for( x = 1; x < i_src_visible - 1; x++ ) { if( p_grad[y*i_src_visible+x] > 40 ) { switch( p_theta[y*i_src_visible+x] ) { case THETA_Y: if( p_grad[y*i_src_visible+x] > p_grad[(y-1)*i_src_visible+x] && p_grad[y*i_src_visible+x] > p_grad[(y+1)*i_src_visible+x] ) { p_outpix[y*i_dst_pitch+x] = 0; } else goto colorize; break; case THETA_P: if( p_grad[y*i_src_visible+x] > p_grad[(y-1)*i_src_visible+x-1] && p_grad[y*i_src_visible+x] > p_grad[(y+1)*i_src_visible+x+1] ) { p_outpix[y*i_dst_pitch+x] = 0; } else goto colorize; break; case THETA_M: if( p_grad[y*i_src_visible+x] > p_grad[(y-1)*i_src_visible+x+1] && p_grad[y*i_src_visible+x] > p_grad[(y+1)*i_src_visible+x-1] ) { p_outpix[y*i_dst_pitch+x] = 0; } else goto colorize; break; case THETA_X: if( p_grad[y*i_src_visible+x] > p_grad[y*i_src_visible+x-1] && p_grad[y*i_src_visible+x] > p_grad[y*i_src_visible+x+1] ) { p_outpix[y*i_dst_pitch+x] = 0; } else goto colorize; break; } } else { colorize: if( p_vout->p_sys->b_cartoon ) { if( p_smooth[y*i_src_visible+x] > 0xa0 ) p_outpix[y*i_dst_pitch+x] = (uint8_t) 0xff - ((0xff - p_inpix[y*i_src_pitch+x] )>>2); else if( p_smooth[y*i_src_visible+x] > 0x70 ) p_outpix[y*i_dst_pitch+x] =(uint8_t) 0xa0 - ((0xa0 - p_inpix[y*i_src_pitch+x] )>>2); else if( p_smooth[y*i_src_visible+x] > 0x28 ) p_outpix[y*i_dst_pitch+x] =(uint8_t) 0x70 - ((0x70 - p_inpix[y*i_src_pitch+x] )>>2); else p_outpix[y*i_dst_pitch+x] =(uint8_t) 0x28 - ((0x28 - p_inpix[y*i_src_pitch+x] )>>2); } } } } if( p_smooth ) free( p_smooth ); if( p_grad ) free( p_grad ); if( p_theta) free( p_theta );}/***************************************************************************** * DistortHough *****************************************************************************/#define p_pre_hough p_vout->p_sys->p_pre_houghstatic void DistortHough( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ int x, y, i; int i_src_visible = p_inpic->p[Y_PLANE].i_visible_pitch; int i_dst_pitch = p_outpic->p[Y_PLANE].i_pitch; int i_num_lines = p_inpic->p[Y_PLANE].i_visible_lines; uint8_t *p_outpix = p_outpic->p[Y_PLANE].p_pixels; int i_diag = sqrt( i_num_lines * i_num_lines + i_src_visible * i_src_visible); int i_max, i_phi_max, i_rho, i_rho_max; int i_nb_steps = 90; double d_step = M_PI / i_nb_steps; double d_sin; double d_cos; uint32_t *p_smooth; int *p_hough = malloc( i_diag * i_nb_steps * sizeof(int) ); if( ! p_hough ) return; p_smooth = (uint32_t *)malloc( i_num_lines*i_src_visible*sizeof(uint32_t)); if( !p_smooth ) return; if( ! p_pre_hough ) { msg_Dbg(p_vout, "Starting precalculation"); p_pre_hough = malloc( i_num_lines*i_src_visible*i_nb_steps*sizeof(int)); if( ! p_pre_hough ) return; for( i = 0 ; i < i_nb_steps ; i++) { d_sin = sin(d_step * i); d_cos = cos(d_step * i); for( y = 0 ; y < i_num_lines ; y++ ) for( x = 0 ; x < i_src_visible ; x++ ) { p_pre_hough[(i*i_num_lines+y)*i_src_visible + x] = ceil(x*d_sin + y*d_cos); } } msg_Dbg(p_vout, "Precalculation done"); } memset( p_hough, 0, i_diag * i_nb_steps * sizeof(int) ); p_vout->p_vlc->pf_memcpy( p_outpic->p[Y_PLANE].p_pixels, p_inpic->p[Y_PLANE].p_pixels, p_outpic->p[Y_PLANE].i_lines * p_outpic->p[Y_PLANE].i_pitch ); p_vout->p_vlc->pf_memcpy( p_outpic->p[U_PLANE].p_pixels, p_inpic->p[U_PLANE].p_pixels, p_outpic->p[U_PLANE].i_lines * p_outpic->p[U_PLANE].i_pitch ); p_vout->p_vlc->pf_memcpy( p_outpic->p[V_PLANE].p_pixels, p_inpic->p[V_PLANE].p_pixels, p_outpic->p[V_PLANE].i_lines * p_outpic->p[V_PLANE].i_pitch ); GaussianConvolution( p_inpic, p_smooth ); /* Sobel gradient | -1 0 1 | | 1 2 1 | | -2 0 2 | and | 0 0 0 | | -1 0 1 | | -1 -2 -1 | */ i_max = 0; i_rho_max = 0; i_phi_max = 0; for( y = 4; y < i_num_lines - 4; y++ ) { for( x = 4; x < i_src_visible - 4; x++ ) { uint32_t a = ( abs( ( ( p_smooth[(y-1)*i_src_visible+x] - p_smooth[(y+1)*i_src_visible+x] ) <<1 ) + ( p_smooth[(y-1)*i_src_visible+x-1] - p_smooth[(y+1)*i_src_visible+x-1] ) + ( p_smooth[(y-1)*i_src_visible+x+1] - p_smooth[(y+1)*i_src_visible+x+1] ) ) + abs( ( ( p_smooth[y*i_src_visible+x-1] - p_smooth[y*i_src_visible+x+1] ) <<1 ) + ( p_smooth[(y-1)*i_src_visible+x-1] - p_smooth[(y-1)*i_src_visible+x+1] ) + ( p_smooth[(y+1)*i_src_visible+x-1] - p_smooth[(y+1)*i_src_visible+x+1] ) ) ); if( a>>8 ) { for( i = 0 ; i < i_nb_steps ; i ++ ) { i_rho = p_pre_hough[(i*i_num_lines+y)*i_src_visible + x]; if( p_hough[i_rho + i_diag/2 + i * i_diag]++ > i_max ) { i_max = p_hough[i_rho + i_diag/2 + i * i_diag]; i_rho_max = i_rho; i_phi_max = i; } } } } } d_sin = sin(i_phi_max*d_step); d_cos = cos(i_phi_max*d_step); if( d_cos != 0 ) { for( x = 0 ; x < i_src_visible ; x++ ) { y = (i_rho_max - x * d_sin) / d_cos; if( y >= 0 && y < i_num_lines ) p_outpix[y*i_dst_pitch+x] = 255; } } if( p_hough ) free( p_hough ); if( p_smooth ) free( p_smooth );}#undef p_pre_hough/***************************************************************************** * DistortPsychedelic *****************************************************************************/static void DistortPsychedelic( vout_thread_t *p_vout, picture_t *p_inpic, picture_t *p_outpic ){ unsigned int w, h; int x,y; uint8_t u,v; video_format_t fmt_out = {0}; picture_t *p_converted; if( !p_vout->p_sys->p_image ) p_vout->p_sys->p_image = image_HandlerCreate( p_vout ); /* chrominance */ u = p_vout->p_sys->u; v = p_vout->p_sys->v; for( y = 0; y<p_outpic->p[U_PLANE].i_lines; y++) { memset( p_outpic->p[U_PLANE].p_pixels+y*p_outpic->p[U_PLANE].i_pitch, u, p_outpic->p[U_PLANE].i_pitch ); memset( p_outpic->p[V_PLANE].p_pixels+y*p_outpic->p[V_PLANE].i_pitch, v, p_outpic->p[V_PLANE].i_pitch ); if( v == 0 && u != 0 ) u --; else if( u == 0xff ) v --; else if( v == 0xff ) u ++; else if( u == 0 ) v ++; } /* luminance */ p_vout->p_vlc->pf_memcpy( p_outpic->p[Y_PLANE].p_pixels, p_inpic->p[Y_PLANE].p_pixels, p_outpic->p[Y_PLANE].i_lines * p_outpic->p[Y_PLANE].i_pitch ); /* image visualization */ fmt_out = p_vout->fmt_out; fmt_out.i_width = p_vout->render.i_width*p_vout->p_sys->scale/150; fmt_out.i_height = p_vout->render.i_height*p_vout->p_sys->scale/150; p_converted = image_Convert( p_vout->p_sys->p_image, p_inpic, &(p_inpic->format), &fmt_out );#define copyimage( plane, b ) \ for( y=0; y<p_converted->p[plane].i_visible_lines; y++) { \ for( x=0; x<p_converted->p[plane].i_visible_pitch; x++) { \ int nx, ny; \ if( p_vout->p_sys->yinc == 1 ) \ ny= y; \ else \ ny = p_converted->p[plane].i_visible_lines-y; \ if( p_vout->p_sys->xinc == 1 ) \ nx = x; \ else \ nx = p_converted->p[plane].i_visible_pitch-x; \ p_outpic->p[plane].p_pixels[(p_vout->p_sys->x*b+nx)+(ny+p_vout->p_sys->y*b)*p_outpic->p[plane].i_pitch ] = p_converted->p[plane].p_pixels[y*p_converted->p[plane].i_pitch+x]; \ } } copyimage( Y_PLANE, 2 ); copyimage( U_PLANE, 1 ); copyimage( V_PLANE, 1 );#undef copyimage p_converted->pf_release( p_converted ); p_vout->p_sys->x += p_vout->p_sys->xinc; p_vout->p_sys->y += p_vout->p_sys->yinc; p_vout->p_sys->scale += p_vout->p_sys->scaleinc; if( p_vout->p_sys->scale >= 50 ) p_vout->p_sys->scaleinc = -1; if( p_vout->p_sys->scale <= 1 ) p_vout->p_sys->scaleinc = 1; w = p_vout->render.i_width*p_vout->p_sys->scale/150; h = p_vout->render.i_height*p_vout->p_sys->scale/150; if( p_vout->p_sys->x*2 + w >= p_vout->render.i_width ) p_vout->p_sys->xinc = -1; if( p_vout->p_sys->x <= 0 ) p_vout->p_sys->xinc = 1; if( p_vout->p_sys->x*2 + w >= p_vout->render.i_width ) p_vout->p_sys->x = (p_vout->render.i_width-w)/2; if( p_vout->p_sys->y*2 + h >= p_vout->render.i_height ) p_vout->p_sys->y = (p_vout->render.i_height-h)/2; if( p_vout->p_sys->y*2 + h >= p_vout->render.i_height ) p_vout->p_sys->yinc = -1; if( p_vout->p_sys->y <= 0 ) p_vout->p_sys->yinc = 1; for( y = 0; y< 16; y++ ) { if( p_vout->p_sys->v == 0 && p_vout->p_sys->u != 0 ) p_vout->p_sys->u -= 1; else if( p_vout->p_sys->u == 0xff ) p_vout->p_sys->v -= 1; else if( p_vout->p_sys->v == 0xff ) p_vout->p_sys->u += 1; else if( p_vout->p_sys->u == 0 ) p_vout->p_sys->v += 1; }}/***************************************************************************** * SendEvents: forward mouse and keyboard events to the parent p_vout *****************************************************************************/static int SendEvents( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ var_Set( (vlc_object_t *)p_data, psz_var, newval ); return VLC_SUCCESS;}/***************************************************************************** * SendEventsToChild: forward events to the child/children vout *****************************************************************************/static int SendEventsToChild( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ vout_thread_t *p_vout = (vout_thread_t *)p_this; var_Set( p_vout->p_sys->p_vout, psz_var, newval ); return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -