PR #23772 opened by joeha URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23772 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23772.patch
This is a patch for the delogo filter. With this I can create a circular or elliptic zone to apply the delogo algorithm. The borders are defined with x,y,w,h parameter just like the rectangular area definition. To become circular I added an additional parameter 'r'=0/1 defaulting to '0' i.e. rectangular area definition. I added a large comment to the function body describing the calculation of the ellipse. Hope you don't mind. The patch now includes a description of the 'r' parameter for the html and man pages. The patch has been rebased to the current master branch, tested with 'make fate-rsync fate' and applies clean to the master branch >From 504a940a74627f0fa5c3f51fd631acc560592fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Habenicht?= <[email protected]> Date: Fri, 31 Jan 2025 22:39:37 +0100 Subject: [PATCH 1/4] avfilter/delogo: add parameter to switch on circular delogo Add a parameter (boolean) r to switch the area from rectangular (r=0) to circular(r=1) delogo. --- libavfilter/vf_delogo.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 83f7f66ad5..74c1aca101 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -195,7 +195,7 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, typedef struct DelogoContext { const AVClass *class; - int x, y, w, h, band, show; + int x, y, w, h, band, show, round; char *x_expr, *y_expr, *w_expr, *h_expr; AVExpr *x_pexpr, *y_pexpr, *w_pexpr, *h_pexpr; double var_values[VAR_VARS_NB]; @@ -209,6 +209,7 @@ static const AVOption delogo_options[]= { { "y", "set logo y position", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str = "-1" }, 0, 0, FLAGS }, { "w", "set logo width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "-1" }, 0, 0, FLAGS }, { "h", "set logo height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "-1" }, 0, 0, FLAGS }, + { "r", "logo is round/ellipse", OFFSET(round), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "show", "show delogo area", OFFSET(show), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { NULL } }; @@ -259,8 +260,8 @@ static av_cold int init(AVFilterContext *ctx) s->band = 1; - av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d, w:%d h:%d band:%d show:%d\n", - s->x, s->y, s->w, s->h, s->band, s->show); + av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d, w:%d h:%d band:%d round:%d show:%d\n", + s->x, s->y, s->w, s->h, s->band, s->round, s->show); s->w += s->band*2; s->h += s->band*2; -- 2.52.0 >From 02f73e418ba7fb6a29ca361a55b1967c9993ce1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Habenicht?= <[email protected]> Date: Mon, 3 Feb 2025 21:21:48 +0100 Subject: [PATCH 2/4] avfilter/delogo: added circular delogo algorithm description Added a description of the elliptic formed delogo algorithm. Placed it outside the doxygen function comment. --- libavfilter/vf_delogo.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 74c1aca101..3e4ac4c82e 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -100,6 +100,30 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, int logo_x, int logo_y, int logo_w, int logo_h, unsigned int band, int show, int direct) { + /* Round area algorithm description: + * + * logo_x, logo_y, logo_w and logo_h define the boundaries of the + * ellipse. In the ellipse formula x^2 / a^2 + y^2 / b^2 = 1 let + * a = logo_w/2, b = logo_h/2 and the center of the ellipse + * (0,0) = (logo_x + a, logo_y + b). + * Let the picture dimensions (px,py,pw,ph) := function API(x,y,w,h). + * A point of the picture is transformed into the ellipse coordinates + * by using x = px - (logo_x + a), y = py - (logo_y +b). + * + * A point is inside the ellipse if x^2 / a^2 + y^2 / b^2 <= 1 + * <=> (x + logo_x)^2 / (logo_w / 2)^2 + * + (y + logo_y)^2 / (logo_h / 2)^2 <= 1 + * <=> (px - logo_x - a + logo_x)^2 / (logo_w / 2)^2 + * + (py - logo_y - b + logo_y)^2 / (logo_h / 2)^2 <= 1 + * <=> (px - a)^2 / (logo_w / 2)^2 + * + (py - b)^2 / (logo_h / 2)^2 <= 1 + * <=> ((px - a) / (logo_w / 2))^2 + * + ((py - b) / (logo_h / 2))^2 <= 1 + * + * px is later defined x, py defined y. + * logo_w is later defined logo_w2, logo_h defined logo_h2. + */ + int x, y; uint64_t interp, weightl, weightr, weightt, weightb, weight; uint8_t *xdst, *xsrc; -- 2.52.0 >From f306be64db1ff1c7892312a70417b4aaffee83fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Habenicht?= <[email protected]> Date: Mon, 3 Feb 2025 21:23:14 +0100 Subject: [PATCH 3/4] avfilter/delogo: added the circular delogo algorithm Use the corrected x,y,w,h values with boundaries and clipping to calculate the points inside the ellipse. --- libavfilter/vf_delogo.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 3e4ac4c82e..30a9f18b3e 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -90,6 +90,7 @@ static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void * * @param logo_w width of the logo * @param logo_h height of the logo * @param band the size of the band around the processed area + * @param round whether delogo is applied to a rectangular or round area * @param show show a rectangle around the processed area, useful for * parameters tweaking * @param direct if non-zero perform in-place processing @@ -98,7 +99,7 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, uint8_t *src, int src_linesize, int w, int h, AVRational sar, int logo_x, int logo_y, int logo_w, int logo_h, - unsigned int band, int show, int direct) + unsigned int band, int round, int show, int direct) { /* Round area algorithm description: * @@ -132,6 +133,7 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, unsigned int left_sample, right_sample; int xclipl, xclipr, yclipt, yclipb; int logo_x1, logo_x2, logo_y1, logo_y2; + double a, b, logo_w2, logo_h2; xclipl = FFMAX(-logo_x, 0); xclipr = FFMAX(logo_x+logo_w-w, 0); @@ -147,6 +149,13 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, topright = src+logo_y1 * src_linesize+logo_x2; botleft = src+logo_y2 * src_linesize+logo_x1; + if (round) { + logo_w2 = (logo_x2 - logo_x1) / 2.0; + logo_h2 = (logo_y2 - logo_y1) / 2.0; + a = logo_x1 + logo_w2; + b = logo_y1 + logo_h2; + } + if (!direct) av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h); @@ -171,6 +180,21 @@ static void apply_delogo(uint8_t *dst, int dst_linesize, continue; } + if (round) { + double xf, yf; + /* Evaluate if x,y is inside the ellipse, else continue + * This is the calculation + * (px - a)^2 / (logo_w / 2)^2 + + * (py - b)^2 / (logo_h / 2)^2 <= 1 + */ + xf = ((double)x - a) / logo_w2; + xf *= xf; + yf = ((double)y - b) / logo_h2; + yf *= yf; + if (xf + yf > 1.0) + continue; + } + /* Weighted interpolation based on relative distances, taking SAR into account */ weightl = (uint64_t) (logo_x2-x) * (y-logo_y1) * (logo_y2-y) * sar.den; weightr = (uint64_t)(x-logo_x1) * (y-logo_y1) * (logo_y2-y) * sar.den; @@ -390,7 +414,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AV_CEIL_RSHIFT(s->w + (s->x & ((1<<hsub)-1)), hsub), AV_CEIL_RSHIFT(s->h + (s->y & ((1<<vsub)-1)), vsub), s->band>>FFMIN(hsub, vsub), - s->show, direct); + s->round, s->show, direct); } if (!direct) -- 2.52.0 >From 23a325c611d3368c35ea9220bd1731563035b31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Habenicht?= <[email protected]> Date: Fri, 10 Jul 2026 21:21:13 +0200 Subject: [PATCH 4/4] avfilter/delogo: update the documentation source file added a description of the parameter 'r' to the documentation source files including an example --- doc/filters.texi | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 34219890d4..4661391e35 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -11794,7 +11794,7 @@ The default is @samp{4}. @section delogo Suppress a TV station logo by a simple interpolation of the surrounding -pixels. Just set a rectangle covering the logo and watch it disappear +pixels. Just set a rectangle or circle covering the logo and watch it disappear (and sometimes something even uglier appear - your mileage may vary). It accepts the following parameters: @@ -11815,7 +11815,12 @@ When set to 1, a green rectangle is drawn on the screen to simplify finding the right @var{x}, @var{y}, @var{w}, and @var{h} parameters. The default value is 0. -The rectangle is drawn on the outermost pixels which will be (partly) +@item r +Specify whether the mask got an elliptic or a rectangular shape. When set +to 1 the mask is set to an elliptic shape, setting to 0 sets a rectangular +shape. The default value is 0. + +The rectangle (or ellipse) is drawn on the outermost pixels which will be (partly) replaced with interpolated values. The values of the next pixels immediately outside this rectangle in each direction will be used to compute the interpolated pixel values inside the rectangle. @@ -11832,6 +11837,12 @@ and size 100x77: delogo=x=0:y=0:w=100:h=77 @end example +@item +Set a circle with a radius of 10 and the center to 10,10: +@example +delogo=x=0:y=0:w=20:h=20 +@end example + @end itemize @anchor{derain} -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
