diff mbox series

[FFmpeg-devel,v3,4/4] avfilter/vf_drawbox: support draw specific face by facedetect metadata

Message ID 1589452367-7681-1-git-send-email-lance.lmwang@gmail.com
State New
Headers show
Series Untitled series #1216
Related show

Commit Message

Limin Wang May 14, 2020, 10:32 a.m. UTC
From: Limin Wang <lance.lmwang@gmail.com>

Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
---
 doc/filters.texi         | 13 +++++++++++++
 libavfilter/vf_drawbox.c | 27 +++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)
diff mbox series

Patch

diff --git a/doc/filters.texi b/doc/filters.texi
index 76e12ef..f838dfc 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -9337,6 +9337,12 @@  See below for the list of accepted constants.
 Applicable if the input has alpha. With value @code{1}, the pixels of the painted box
 will overwrite the video's color and alpha pixels.
 Default is @code{0}, which composites the box onto the input, leaving the video's alpha intact.
+
+@item face @var{integer}
+Draw the box onto the position of the nth face as detected by the ocv filter's
+facedetect mode. If no face detection metadata exists
+then the filter will use the specified box parameters instead.
+
 @end table
 
 The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
@@ -9405,6 +9411,13 @@  Draw a 2-pixel red 2.40:1 mask:
 @example
 drawbox=x=-t:y=0.5*(ih-iw/2.4)-t:w=iw+t*2:h=iw/2.4+t*2:t=2:c=red
 @end example
+
+@item
+Draw a red box onto the position of the first face as detected by the ocv
+filter's facedetect method.
+@example
+ocv=filter_name=facedetect:filter_params=facedetect=./haarcascade_frontalface_alt.xml,drawbox=face=0:color=red
+@end example
 @end itemize
 
 @subsection Commands
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index 21d520e..239a149 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -81,6 +81,7 @@  typedef struct DrawBoxContext {
     char *t_expr;          ///< expression for thickness
     int have_alpha;
     int replace;
+    int face;
 } DrawBoxContext;
 
 static const int NUM_EXPR_EVALS = 5;
@@ -220,6 +221,31 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
     int plane, x, y, xb = s->x, yb = s->y;
     unsigned char *row[4];
 
+    if (s->face >= 0) {
+        AVDictionaryEntry *ex, *ey, *ew, *eh;
+        char key2[128];
+        AVDictionary *metadata = frame->metadata;
+
+        snprintf(key2, sizeof(key2), "lavfi.facedetect.%d.%s", s->face, "x");
+        ex = av_dict_get(metadata, key2, NULL, AV_DICT_MATCH_CASE);
+
+        snprintf(key2, sizeof(key2), "lavfi.facedetect.%d.%s", s->face, "y");
+        ey = av_dict_get(metadata, key2, NULL, AV_DICT_MATCH_CASE);
+
+        snprintf(key2, sizeof(key2), "lavfi.facedetect.%d.%s", s->face, "w");
+        ew = av_dict_get(metadata, key2, NULL, AV_DICT_MATCH_CASE);
+
+        snprintf(key2, sizeof(key2), "lavfi.facedetect.%d.%s", s->face, "h");
+        eh = av_dict_get(metadata, key2, NULL, AV_DICT_MATCH_CASE);
+
+        if (ex && ey && ew && eh) {
+            xb = s->x = strtol(ex->value, NULL, 10);
+            yb = s->y = strtol(ey->value, NULL, 10);
+            s->w = strtol(ew->value, NULL, 10);
+            s->h = strtol(eh->value, NULL, 10);
+        }
+    }
+
     if (s->have_alpha && s->replace) {
         for (y = FFMAX(yb, 0); y < frame->height && y < (yb + s->h); y++) {
             row[0] = frame->data[0] + y * frame->linesize[0];
@@ -323,6 +349,7 @@  static const AVOption drawbox_options[] = {
     { "thickness", "set the box thickness",                        OFFSET(t_expr),    AV_OPT_TYPE_STRING, { .str="3" },       0, 0, FLAGS },
     { "t",         "set the box thickness",                        OFFSET(t_expr),    AV_OPT_TYPE_STRING, { .str="3" },       0, 0, FLAGS },
     { "replace",   "replace color & alpha",                        OFFSET(replace),   AV_OPT_TYPE_BOOL,   { .i64=0 },         0,        1,        FLAGS },
+    { "face",      "set which face to draw with metadata",         OFFSET(face),      AV_OPT_TYPE_INT,    { .i64=-1 },        -1,     256,        FLAGS },
     { NULL }
 };