[FFmpeg-cvslog] avfilter/vf_morpho: add gradient operation type

Paul B Mahol git at videolan.org
Wed Sep 29 19:03:49 EEST 2021


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Sep 29 15:32:49 2021 +0200| [b4626da92b06cde20a80a2fa320306eb1b1735dc] | committer: Paul B Mahol

avfilter/vf_morpho: add gradient operation type

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b4626da92b06cde20a80a2fa320306eb1b1735dc
---

 doc/filters.texi        |  1 +
 libavfilter/vf_morpho.c | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/doc/filters.texi b/doc/filters.texi
index 568c2995bc..4f21276abf 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -15374,6 +15374,7 @@ Set morphological transform to apply, can be:
 @item dilate
 @item open
 @item close
+ at item gradient
 @end table
 Default is @code{erode}.
 
diff --git a/libavfilter/vf_morpho.c b/libavfilter/vf_morpho.c
index e45f7522f8..0e0d5d0fa1 100644
--- a/libavfilter/vf_morpho.c
+++ b/libavfilter/vf_morpho.c
@@ -39,6 +39,7 @@ enum MorphModes {
     DILATE,
     OPEN,
     CLOSE,
+    GRADIENT,
     NB_MODES
 };
 
@@ -53,6 +54,7 @@ typedef struct IPlane {
     void (*min_out_place)(uint8_t *c, const uint8_t *a, const uint8_t *b, int x);
     void (*max_in_place)(uint8_t *a, const uint8_t *b, int x);
     void (*min_in_place)(uint8_t *a, const uint8_t *b, int x);
+    void (*diff_in_place)(uint8_t *a, const uint8_t *b, int x);
 } IPlane;
 
 typedef struct LUT {
@@ -124,6 +126,7 @@ static const AVOption morpho_options[] = {
     { "dilate", NULL,                                         0,                  AV_OPT_TYPE_CONST, {.i64=DILATE}, 0,  0, FLAGS, "mode" },
     { "open",   NULL,                                         0,                  AV_OPT_TYPE_CONST, {.i64=OPEN},   0,  0, FLAGS, "mode" },
     { "close",  NULL,                                         0,                  AV_OPT_TYPE_CONST, {.i64=CLOSE},  0,  0, FLAGS, "mode" },
+    { "gradient",NULL,                                        0,                  AV_OPT_TYPE_CONST, {.i64=GRADIENT},0, 0, FLAGS, "mode" },
     { "planes",  "set planes to filter",                      OFFSET(planes),     AV_OPT_TYPE_INT,   {.i64=7}, 0, 15, FLAGS },
     { "structure", "when to process structures",              OFFSET(structures), AV_OPT_TYPE_INT,   {.i64=1}, 0,  1, FLAGS, "str" },
     {   "first", "process only first structure, ignore rest", 0,                  AV_OPT_TYPE_CONST, {.i64=0}, 0,  0, FLAGS, "str" },
@@ -184,6 +187,12 @@ static void maxinplace_fun(uint8_t *a, const uint8_t *b, int x)
         a[i] = FFMAX(a[i], b[i]);
 }
 
+static void diffinplace_fun(uint8_t *a, const uint8_t *b, int x)
+{
+    for (int i = 0; i < x; i++)
+        a[i] -= b[i];
+}
+
 static void min16_fun(uint8_t *cc, const uint8_t *aa, const uint8_t *bb, int x)
 {
     const uint16_t *a = (const uint16_t *)aa;
@@ -203,6 +212,15 @@ static void mininplace16_fun(uint8_t *aa, const uint8_t *bb, int x)
         a[i] = FFMIN(a[i], b[i]);
 }
 
+static void diffinplace16_fun(uint8_t *aa, const uint8_t *bb, int x)
+{
+    uint16_t *a = (uint16_t *)aa;
+    const uint16_t *b = (const uint16_t *)bb;
+
+    for (int i = 0; i < x; i++)
+        a[i] -= b[i];
+}
+
 static void max16_fun(uint8_t *cc, const uint8_t *aa, const uint8_t *bb, int x)
 {
     const uint16_t *a = (const uint16_t *)aa;
@@ -453,6 +471,12 @@ static int erode(IPlane *g, IPlane *f, chord_set *SE, LUT *Ty)
     return 0;
 }
 
+static void gradient(IPlane *g, IPlane *f)
+{
+    for (int y = 0; y < f->h; y++)
+        f->diff_in_place(g->img[y], f->img[y], f->w);
+}
+
 static int insert_chord_set(chord_set *chords, chord c)
 {
     // Checking if chord fits in dynamic array, resize if not.
@@ -689,6 +713,7 @@ static int read_iplane(IPlane *imp, const uint8_t *dst, int dst_linesize,
     imp->min_out_place = type_size == 1 ? min_fun : min16_fun;
     imp->max_in_place = type_size == 1 ? maxinplace_fun : maxinplace16_fun;
     imp->min_in_place = type_size == 1 ? mininplace_fun : mininplace16_fun;
+    imp->diff_in_place = type_size == 1 ? diffinplace_fun : diffinplace16_fun;
 
     for (int y = 0; y < h; y++)
         imp->img[y] = (uint8_t *)dst + y * dst_linesize;
@@ -832,6 +857,18 @@ copy:
                 break;
             ret = erode(&s->g[p], &s->h[p], &s->SE[p], &s->Ty[1][p]);
             break;
+        case GRADIENT:
+            ret = read_iplane(&s->h[p], s->temp->data[p], s->temp->linesize[p], width, height, 1, type_size, depth);
+            if (ret < 0)
+                break;
+            ret = dilate(&s->g[p], &s->f[p], &s->SE[p], &s->Ty[0][p]);
+            if (ret < 0)
+                break;
+            ret = erode(&s->h[p], &s->f[p], &s->SE[p], &s->Ty[1][p]);
+            if (ret < 0)
+                return ret;
+            gradient(&s->g[p], &s->h[p]);
+            break;
         default:
             av_assert0(0);
         }



More information about the ffmpeg-cvslog mailing list