⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 motiondetect.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    if( !p_sys->b_old )    {        picture_Copy( p_sys->p_old, p_inpic );        p_sys->b_old = true;        return p_inpic;    }    p_outpic = filter_NewPicture( p_filter );    if( !p_outpic )    {        picture_Release( p_inpic );        return NULL;    }    picture_Copy( p_outpic, p_inpic );    /* Substract all planes at once */    for( y = 0; y < p_fmt->i_height; y++ )    {        for( x = 0; x < p_fmt->i_width; x+=2 )        {            int i;            int d;            d = abs( p_inpix[y*i_src_pitch+2*x+i_u_offset] - p_oldpix[y*i_old_pitch+2*x+i_u_offset] ) +                abs( p_inpix[y*i_src_pitch+2*x+i_v_offset] - p_oldpix[y*i_old_pitch+2*x+i_v_offset] );            for( i = 0; i < 2; i++ )                p_buf2[y*p_fmt->i_width+x+i] =                    abs( p_inpix[y*i_src_pitch+2*(x+i)+i_y_offset] - p_oldpix[y*i_old_pitch+2*(x+i)+i_y_offset] ) + d;        }    }    /**     * Get the areas where movement was detected     */    p_sys->i_colors = FindShapes( p_buf2, p_buf, p_fmt->i_width, p_fmt->i_width, p_fmt->i_height,                                  p_sys->colors, p_sys->color_x_min, p_sys->color_x_max, p_sys->color_y_min, p_sys->color_y_max );    /**     * Count final number of shapes     * Draw rectangles (there can be more than 1 moving shape in 1 rectangle)     */    Draw( p_filter, &p_outpic->p[Y_PLANE].p_pixels[i_y_offset], p_outpic->p[Y_PLANE].i_pitch, 2 );    /**     * We're done. Lets keep a copy of the picture     * TODO we may just picture_Release with a latency of 1 if the filters/vout     * handle it correctly */    picture_Copy( p_sys->p_old, p_inpic );    picture_Release( p_inpic );    return p_outpic;}/***************************************************************************** * Gaussian Convolution ***************************************************************************** *    Gaussian convolution ( sigma == 1.4 ) * *    |  2  4  5  4  2  |   |  2  4  4  4  2 | *    |  4  9 12  9  4  |   |  4  8 12  8  4 | *    |  5 12 15 12  5  | ~ |  4 12 16 12  4 | *    |  4  9 12  9  4  |   |  4  8 12  8  4 | *    |  2  4  5  4  2  |   |  2  4  4  4  2 | *****************************************************************************/static void GaussianConvolution( uint32_t *p_inpix, uint32_t *p_smooth,                                 int i_src_pitch, int i_num_lines,                                 int i_src_visible ){    int x,y;    /* A bit overkill but ... simpler */    memset( p_smooth, 0, sizeof(*p_smooth) * i_src_pitch * i_num_lines );    for( y = 2; y < i_num_lines - 2; y++ )    {        for( x = 2; x < i_src_visible - 2; x++ )        {            p_smooth[y*i_src_visible+x] = (uint32_t)(              /* 2 rows up */                ( p_inpix[(y-2)*i_src_pitch+x-2] )              + ((p_inpix[(y-2)*i_src_pitch+x-1]              +   p_inpix[(y-2)*i_src_pitch+x]              +   p_inpix[(y-2)*i_src_pitch+x+1])<<1 )              + ( p_inpix[(y-2)*i_src_pitch+x+2] )              /* 1 row up */              + ((p_inpix[(y-1)*i_src_pitch+x-2]              + ( p_inpix[(y-1)*i_src_pitch+x-1]<<1 )              + ( p_inpix[(y-1)*i_src_pitch+x]*3 )              + ( p_inpix[(y-1)*i_src_pitch+x+1]<<1 )              +   p_inpix[(y-1)*i_src_pitch+x+2]              /* */              +   p_inpix[y*i_src_pitch+x-2]              + ( p_inpix[y*i_src_pitch+x-1]*3 )              + ( p_inpix[y*i_src_pitch+x]<<2 )              + ( p_inpix[y*i_src_pitch+x+1]*3 )              +   p_inpix[y*i_src_pitch+x+2]              /* 1 row down */              +   p_inpix[(y+1)*i_src_pitch+x-2]              + ( p_inpix[(y+1)*i_src_pitch+x-1]<<1 )              + ( p_inpix[(y+1)*i_src_pitch+x]*3 )              + ( p_inpix[(y+1)*i_src_pitch+x+1]<<1 )              +   p_inpix[(y+1)*i_src_pitch+x+2] )<<1 )              /* 2 rows down */              + ( p_inpix[(y+2)*i_src_pitch+x-2] )              + ((p_inpix[(y+2)*i_src_pitch+x-1]              +   p_inpix[(y+2)*i_src_pitch+x]              +   p_inpix[(y+2)*i_src_pitch+x+1])<<1 )              + ( p_inpix[(y+2)*i_src_pitch+x+2] )              ) >> 6 /* 115 */;        }    }}/***************************************************************************** * *****************************************************************************/static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,                       int i_pitch, int i_visible, int i_lines,                       int *colors,                       int *color_x_min, int *color_x_max,                       int *color_y_min, int *color_y_max ){    int last = 1;    int i, j;    /**     * Apply some smoothing to remove noise     */    GaussianConvolution( p_diff, p_smooth, i_pitch, i_lines, i_visible );    /**     * Label the shapes and build the labels dependencies list     */    for( j = 0; j < i_pitch; j++ )    {        p_smooth[j] = 0;        p_smooth[(i_lines-1)*i_pitch+j] = 0;    }    for( i = 1; i < i_lines-1; i++ )    {        p_smooth[i*i_pitch] = 0;        for( j = 1; j < i_pitch-1; j++ )        {            if( p_smooth[i*i_pitch+j] > 15 )            {                if( p_smooth[(i-1)*i_pitch+j-1] )                {                    p_smooth[i*i_pitch+j] = p_smooth[(i-1)*i_pitch+j-1];                }                else if( p_smooth[(i-1)*i_pitch+j] )                    p_smooth[i*i_pitch+j] = p_smooth[(i-1)*i_pitch+j];                else if( p_smooth[i*i_pitch+j-1] )                    p_smooth[i*i_pitch+j] = p_smooth[i*i_pitch+j-1];                else                {                    if( last < NUM_COLORS )                    {                        p_smooth[i*i_pitch+j] = last;                        colors[last] = last;                        last++;                    }                }                #define CHECK( A ) \                if( p_smooth[A] && p_smooth[A] != p_smooth[i*i_pitch+j] ) \                { \                    if( p_smooth[A] < p_smooth[i*i_pitch+j] ) \                        colors[p_smooth[i*i_pitch+j]] = p_smooth[A]; \                    else \                        colors[p_smooth[A]] = p_smooth[i*i_pitch+j]; \                }                CHECK( i*i_pitch+j-1 );                CHECK( (i-1)*i_pitch+j-1 );                CHECK( (i-1)*i_pitch+j );                CHECK( (i-1)*i_pitch+j+1 );                #undef CHECK            }            else            {                p_smooth[i*i_pitch+j] = 0;            }        }        p_smooth[i*i_pitch+j] = 0;    }    /**     * Initialise empty rectangle list     */    for( i = 1; i < last; i++ )    {        color_x_min[i] = -1;        color_x_max[i] = -1;        color_y_min[i] = -1;        color_y_max[i] = -1;    }    /**     * Compute rectangle coordinates     */    for( i = 0; i < i_pitch * i_lines; i++ )    {        if( p_smooth[i] )        {            while( colors[p_smooth[i]] != (int)p_smooth[i] )                p_smooth[i] = colors[p_smooth[i]];            if( color_x_min[p_smooth[i]] == -1 )            {                color_x_min[p_smooth[i]] =                color_x_max[p_smooth[i]] = i % i_pitch;                color_y_min[p_smooth[i]] =                color_y_max[p_smooth[i]] = i / i_pitch;            }            else            {                int x = i % i_pitch, y = i / i_pitch;                if( x < color_x_min[p_smooth[i]] )                    color_x_min[p_smooth[i]] = x;                if( x > color_x_max[p_smooth[i]] )                    color_x_max[p_smooth[i]] = x;                if( y < color_y_min[p_smooth[i]] )                    color_y_min[p_smooth[i]] = y;                if( y > color_y_max[p_smooth[i]] )                    color_y_max[p_smooth[i]] = y;            }        }    }    /**     * Merge overlaping rectangles     */    for( i = 1; i < last; i++ )    {        if( colors[i] != i ) continue;        if( color_x_min[i] == -1 ) continue;        for( j = i+1; j < last; j++ )        {            if( colors[j] != j ) continue;            if( color_x_min[j] == -1 ) continue;            if( __MAX( color_x_min[i], color_x_min[j] ) < __MIN( color_x_max[i], color_x_max[j] ) &&                __MAX( color_y_min[i], color_y_min[j] ) < __MIN( color_y_max[i], color_y_max[j] ) )            {                color_x_min[i] = __MIN( color_x_min[i], color_x_min[j] );                color_x_max[i] = __MAX( color_x_max[i], color_x_max[j] );                color_y_min[i] = __MIN( color_y_min[i], color_y_min[j] );                color_y_max[i] = __MAX( color_y_max[i], color_y_max[j] );                color_x_min[j] = -1;                j = 0;            }        }    }    return last;}static void Draw( filter_t *p_filter, uint8_t *p_pix, int i_pix_pitch, int i_pix_size ){    filter_sys_t *p_sys = p_filter->p_sys;    int i, j;    for( i = 1, j = 0; i < p_sys->i_colors; i++ )    {        int x, y;        if( p_sys->colors[i] != i )            continue;        const int color_x_min = p_sys->color_x_min[i];        const int color_x_max = p_sys->color_x_max[i];        const int color_y_min = p_sys->color_y_min[i];        const int color_y_max = p_sys->color_y_max[i];        if( color_x_min == -1 )            continue;        if( ( color_y_max - color_y_min ) * ( color_x_max - color_x_min ) < 16 )            continue;        j++;        y = color_y_min;        for( x = color_x_min; x <= color_x_max; x++ )            p_pix[y*i_pix_pitch+x*i_pix_size] = 0xff;        y = color_y_max;        for( x = color_x_min; x <= color_x_max; x++ )            p_pix[y*i_pix_pitch+x*i_pix_size] = 0xff;        x = color_x_min;        for( y = color_y_min; y <= color_y_max; y++ )            p_pix[y*i_pix_pitch+x*i_pix_size] = 0xff;        x = color_x_max;        for( y = color_y_min; y <= color_y_max; y++ )            p_pix[y*i_pix_pitch+x*i_pix_size] = 0xff;    }    msg_Dbg( p_filter, "Counted %d moving shapes.", j );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -