[FFmpeg-devel] Suggestion: limit deshake to specific area to search for motion vectors.

Michael Niedermayer michaelni at gmx.at
Wed Oct 19 18:57:05 CEST 2011


On Wed, Oct 19, 2011 at 04:14:32PM +0100, Paul Flinders wrote:
> Hi,
> 
> I've been playing with the new deshake filter - very good stuff.
> However one of the clips that I need to remove camera shake from has
> a small problem - partway through a group of people all bob down
> simultaneously, then stand back up again. This confuses the search
> for the global motion vector somewhat.
> 
> I've patched the code so that the deshake filter arguments include a
> bounding box to limit the area of the picture which works very well
> for this problem.
> 
> Patch attached, thoughts?

>  vf_deshake.c         |   39 ++++++++++++++++++++++++++++++++++-----
>  vf_deshake.c.deshake |only
>  2 files changed, 34 insertions(+), 5 deletions(-)
> 25297b581768ad090aac42db56c6a4606e119233  ffmpeg-deshake.patch
> diff -ur -x '*~' a/ffmpeg-20111019/libavfilter/vf_deshake.c b/ffmpeg-20111019/libavfilter/vf_deshake.c
> --- a/ffmpeg-20111019/libavfilter/vf_deshake.c	2011-10-19 07:20:10.000000000 +0100
> +++ b/ffmpeg-20111019/libavfilter/vf_deshake.c	2011-10-19 15:46:18.000000000 +0100
> @@ -92,6 +92,10 @@
>      int refcount;              ///< Number of reference frames (defines averaging window)
>      FILE *fp;
>      Transform avg;
> +    int cw;		       ///< Crop motion search to this box
> +    int ch;
> +    int cx;
> +    int cy;
>  } DeshakeContext;
>  
>  static int cmp(const double *a, const double *b)
> @@ -339,10 +343,17 @@
>      deshake->blocksize = 8;
>      deshake->contrast = 125;
>      deshake->search = EXHAUSTIVE;

> -    deshake->refcount = 20;
> +    deshake->refcount = 10;
> +    

this change looks unrelated, also theres trailing whitespace and tabs
(which arent allowed in ffmpeg git)



> +    deshake->cw = -1;
> +    deshake->ch = -1;
> +    deshake->cx = -1;
> +    deshake->cy = -1;
>  
>      if (args) {
> -        sscanf(args, "%d:%d:%d:%d:%d:%d:%255s", &deshake->rx, &deshake->ry, (int *)&deshake->edge,
> +        sscanf(args, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%255s", 
> +	       &deshake->cx, &deshake->cy, &deshake->cw, &deshake->ch, 
> +	       &deshake->rx, &deshake->ry, (int *)&deshake->edge,
>                 &deshake->blocksize, &deshake->contrast, (int *)&deshake->search, filename);
>  
>          deshake->blocksize /= 2;
> @@ -353,13 +364,20 @@
>          deshake->blocksize = av_clip(deshake->blocksize, 4, 128);
>          deshake->contrast = av_clip(deshake->contrast, 1, 255);
>          deshake->search = av_clip(deshake->search, EXHAUSTIVE, SEARCH_COUNT - 1);
> +
>      }
>      if (*filename)
>          deshake->fp = fopen(filename, "w");
>      if (deshake->fp)
>          fwrite("Ori x, Avg x, Fin x, Ori y, Avg y, Fin y, Ori angle, Avg angle, Fin angle, Ori zoom, Avg zoom, Fin zoom\n", sizeof(char), 104, deshake->fp);
>  
> -    av_log(ctx, AV_LOG_INFO, "rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n",
> +    if (deshake->cx > 0)
> +	deshake->cx &= ~15;
> +    if (deshake->cy > 0)
> +	deshake->cy &= ~15;
> +
> +    av_log(ctx, AV_LOG_INFO, "cx: %d, cy: %d, cw: %d, ch: %d, rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n",
> +	   deshake->cx, deshake->cy, deshake->cw, deshake->ch,
>             deshake->rx, deshake->ry, deshake->edge, deshake->blocksize * 2, deshake->contrast, deshake->search);
>  
>      return 0;
> @@ -414,8 +432,19 @@
>      char tmp[256];
>      Transform orig;
>  
> -    // Find the most likely global motion for the current frame
> -    find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t);
> +    if (deshake->cx < 0) {
> +	// Find the most likely global motion for the current frame
> +	find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t);
> +    } else {
> +	uint8_t *src1 = (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0];
> +	uint8_t *src2 = in->data[0];
> +
> +	src1 += deshake->cy * in->linesize[0] + deshake->cx;
> +	src2 += deshake->cy * in->linesize[0] + deshake->cx;
> +
> +	find_motion(deshake, src1, src2, deshake->cw, deshake->ch, in->linesize[0], &t);
> +    }

I think there is insufficient validation of the c* values

Please resubmit the patch with the issues fixed, thanks

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

If you think the mosad wants you dead since a long time then you are either
wrong or dead since a long time.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20111019/dc9082a4/attachment.asc>


More information about the ffmpeg-devel mailing list