stable-diffusion

How to properly set the settings of the Reactor face swapping extension for Stable Diffusion through a POST api call?


I'm trying to create an application to send some calls to Stable Diffusion and use the ReActor extension (https://github.com/Gourieff/sd-webui-reactor) to do some face swapping.

I'm using the API Payload extension (https://github.com/huchenlei/sd-webui-api-payload-display) to know what are the parameters to send in the body of the api call.

Within Stable Diffusion web UI, I'm using the "Inpaint Upload" tab to set the source and mask images. Then in the ReActor settings, I set the face image to use as replacement.

The json data generated by the Api Payload looks like this :

{
    "alwayson_scripts": {
        "API payload": {
            "args": []
        },
        "Extra options": {
            "args": []
        },
        "ReActor": {
            "args": [{
                    "_category": 0,
                    "_exif": null,
                    "_size": [512, 512],
                    "im": null,
                    "info": {
                        "background": [255, 255, 255, 255],
                        "duration": 0,
                        "loop": 1,
                        "timestamp": 0
                    },
                    "mode": "RGB",
                    "palette": null,
                    "pyaccess": null,
                    "readonly": 0
                }, true, "0", "0", "inswapper_128.onnx", "CodeFormer", 1, true, "None", 1, 1, false, true, 1, 0, 0, false, 0.5, true, false, "CUDA", false, 0, "None", "", null]
        },
        "Refiner": {
            "args": [false, "", 0.8]
        },
        "Seed": {
            "args": [-1, false, -1, 0, 0, 0]
        }
    },
    "batch_size": 1,
    "cfg_scale": 7,
    "comments": {},
    "denoising_strength": 0.75,
    "disable_extra_networks": false,
    "do_not_save_grid": false,
    "do_not_save_samples": false,
    "height": 512,
    "image_cfg_scale": 1.5,
    "init_images": ["base64image placeholder"],
    "initial_noise_multiplier": 1.0,
    "inpaint_full_res": 1,
    "inpaint_full_res_padding": 32,
    "inpainting_fill": 1,
    "inpainting_mask_invert": 0,
    "mask_blur": 4,
    "mask_blur_x": 4,
    "mask_blur_y": 4,
    "n_iter": 1,
    "negative_prompt": "",
    "override_settings": {},
    "override_settings_restore_afterwards": true,
    "prompt": "",
    "resize_mode": 0,
    "restore_faces": false,
    "s_churn": 0.0,
    "s_min_uncond": 0.0,
    "s_noise": 1.0,
    "s_tmax": null,
    "s_tmin": 0.0,
    "sampler_name": "DPM++ 2M Karras",
    "script_args": [],
    "script_name": null,
    "seed": -1,
    "seed_enable_extras": true,
    "seed_resize_from_h": -1,
    "seed_resize_from_w": -1,
    "steps": 42,
    "styles": [],
    "subseed": -1,
    "subseed_strength": 0,
    "tiling": false,
    "width": 512
}

I understand that I have to set the "init_images" property to a base64 encoded image of the source picture, I also add a "mask" property (which is missing here) with a base64 encode version of the mask picture. (not sure if this is working at this stage) But I can't find how to properly set the image data for the ReActor settings part.

I send these json data through a POST HttpWebRequest in C#, and it seems to be properly received and treated by Stable diffusion, except for the ReActor part.

I tried to put a base64 encoded version of my new face image in the "im" property (here with a null value in the json example), but this is generating a python error in ReActor :

opencv cvtColor src data type = 17 is not supported

on this line

source_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)

in the reactor_swapper.py file.

If I print the source_img variable just before this line, I see this instead of the image object that should be provided :

{
    "_category": 0,
    "_exif": null,
    "_size": [512, 512],
    "im": <BASE64_DATA>,
    "info": {
        "background": [255, 255, 255, 255],
        "duration": 0,
        "loop": 1,
        "timestamp": 0
    },
    "mode": "RGB",
    "palette": null,
    "pyaccess": null,
    "readonly": 0
}

(<BASE64_DATA> being the real base64 encoded data string of my picture)

So I guess there is something wrong in the way I send the data to the api, or in how the json data are arranged.


Solution

  • When using basic stable-diffusion API (not external ReActor's one) arguments is just an array, not a map. The source image goes as the first object in this array. Like this:

    {
        "prompt":"boobies",
        "negativePrompt":"sousage",
        "seed":1,
        "sampler_name":"DPM\u002B\u002B 2M Karras",
        "batch_size":1,
        "n_iter":1,
        "steps":25,
        "cfg_scale":2.5,
        "width":1080,
        "height":1080,
        "alwayson_scripts":{
            "reactor":{
                "args":[
                "iVBORw0KGgoAAAANSNocS3O.........AAAAASUVORK5CYII=",
                true,
                "0",
                "0",
                "C:\\stable-diffusion-webui\\models\\insightface\\inswapper_128.onnx",
                "CodeFormer",
                1,
                true,
                "4x_NMKD-Superscale-SP_178000_G",
                2,
                1,
                false,
                true,
                1,
                0,
                0,
                false,
                0.8,
                false,
                false,
                "CUDA"
                ,
                true,
                0
                ]
            }
        }
    }
    

    https://github.com/Gourieff/sd-webui-reactor/blob/main/example/api_example.py