Scripted foreground extraction

Hello,

I’ve tried this tutorial and I think it gives great results:

Compared to grabcut, I think it’s easier to set up a few points than to draw lines and curves. I would like to integrate this with another software. Provided I know foreground and background points coordinates, is there a way to script the extraction (using gmic cli, not gimp) ?

Thanks for your kind help

1 Like

Yes, that’s possible. Basically G’MIC uses a simple watershed technique with a specific potential map, nothing really fancy.
So the main difficulty here is to provide an image where non-zero pixels are your labeled points (e.g. 1=background and 2=foreground). Once you have this, do something as:

$ gmic input.jpg labeled_points.png +_x_segment[0] +watershed[1] [-1]

and you’ll get the full labeled result as the last image.
The command _x_segment is the one used by the G’MIC filter to estimate the potential map from the input image.

Neat ! Looks like it won’t be too much work to integrate. I’ll try this and get back with my results.

Very clear explanations, thank you.

Hello,

I’m getting great results with fewer interactions and very reasonable time given the image size.

I could probably squeeze a bit more time by calling the C lib ?

Yes, I would say the C++ lib is maybe easier to use : https://gmic.eu/libgmic.shtml
Just feed gmic() with a list of two input images, and use the same command as the command string.

Our current stack is python/numpy-based, so calling C++ libs is more involving than calling C libs. It should be possible though, I’ll give it a try.

There is also a C API for the G’MIC library, which works basically the same.
Look at these sources for more info and examples of use : https://github.com/dtschump/gmic-community/tree/master/libcgmic

Ho-hum: maybe I should grit my teeth and learn C(++) some day so that my scripts aren’t so darn slow.

Sorry I didn’t update this thread. Here’s what I did to try to interface gmic with python:

  • compile gmic_libc

  • generate bindings to gmic_libc.h with ctypesgen (https://github.com/davidjamesca/ctypesgen). This automatically converts the structs and the functions to a python module, linked to the .so file.

  • test calling gmic from python. Example, unrelated to my extraction problem:

    import gmic
    from ctypes import POINTER, c_bool, c_float, c_uint

    E_FORMAT_FLOAT = 0
    E_FORMAT_BYTE = 1

    p_bool = POINTER(c_bool)
    p_float = POINTER(c_float)

    options = gmic.gmic_interface_options()
    options.ignore_stdlib = False
    options.p_is_abort = p_bool(c_bool(False))
    options.p_progress = p_float(c_float(0.0))
    options.interleave_output = False
    options.no_inplace_processing = True
    options.output_format = E_FORMAT_FLOAT

    image = gmic.gmic_interface_image()
    image.name = “test”.encode(“utf-8”)
    image.width = 500
    image.height = 500
    image.spectrum = 4
    image.depth = 1
    image.is_interleaved = False
    image.format = E_FORMAT_FLOAT

    command = ‘v 0 apply_channels “div 2”,rgba_r polaroid 5,30 rotate 20 drop_shadow , drgba display’

    gmic.gmic_call(command, c_uint(0), image, options)

So far, so good, it works fine. BUT… I decided not to go this way because in my case the small performance improvement comes at the cost of more boilerplate and above all a packaging problem (it’s just easier to rely on the already available CLI version of GMIC). For my use case it’s just not worth it, but should I need python bindings it would be a good solution to use ctypesgen and maybe a light bridge between gmic_interface_image and numpy.

Thanks again for your help.