mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/vf_morpho: add gradient operation type
This commit is contained in:
parent
d619e82e97
commit
b4626da92b
|
@ -15374,6 +15374,7 @@ Set morphological transform to apply, can be:
|
||||||
@item dilate
|
@item dilate
|
||||||
@item open
|
@item open
|
||||||
@item close
|
@item close
|
||||||
|
@item gradient
|
||||||
@end table
|
@end table
|
||||||
Default is @code{erode}.
|
Default is @code{erode}.
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ enum MorphModes {
|
||||||
DILATE,
|
DILATE,
|
||||||
OPEN,
|
OPEN,
|
||||||
CLOSE,
|
CLOSE,
|
||||||
|
GRADIENT,
|
||||||
NB_MODES
|
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 (*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 (*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 (*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;
|
} IPlane;
|
||||||
|
|
||||||
typedef struct LUT {
|
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" },
|
{ "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" },
|
{ "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" },
|
{ "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 },
|
{ "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" },
|
{ "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" },
|
{ "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]);
|
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)
|
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;
|
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]);
|
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)
|
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;
|
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;
|
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)
|
static int insert_chord_set(chord_set *chords, chord c)
|
||||||
{
|
{
|
||||||
// Checking if chord fits in dynamic array, resize if not.
|
// 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->min_out_place = type_size == 1 ? min_fun : min16_fun;
|
||||||
imp->max_in_place = type_size == 1 ? maxinplace_fun : maxinplace16_fun;
|
imp->max_in_place = type_size == 1 ? maxinplace_fun : maxinplace16_fun;
|
||||||
imp->min_in_place = type_size == 1 ? mininplace_fun : mininplace16_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++)
|
for (int y = 0; y < h; y++)
|
||||||
imp->img[y] = (uint8_t *)dst + y * dst_linesize;
|
imp->img[y] = (uint8_t *)dst + y * dst_linesize;
|
||||||
|
@ -832,6 +857,18 @@ copy:
|
||||||
break;
|
break;
|
||||||
ret = erode(&s->g[p], &s->h[p], &s->SE[p], &s->Ty[1][p]);
|
ret = erode(&s->g[p], &s->h[p], &s->SE[p], &s->Ty[1][p]);
|
||||||
break;
|
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:
|
default:
|
||||||
av_assert0(0);
|
av_assert0(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue