UPDATE: API Support is now ready
VersionUP
This commit is contained in:
parent
c5ec285d67
commit
beb70dc90d
16
README.md
16
README.md
@ -1,6 +1,8 @@
|
|||||||
# NSFW-Roop 0.1.0 for StableDiffusion
|
# Roop-GE 0.2.0 for StableDiffusion
|
||||||
### NSFW (uncensored) version (use it on your own responsibility) of [original sd-webui-roop](https://github.com/s0md3v/sd-webui-roop) with a lot of improvements
|
### NSFW (uncensored) version (use it on your own responsibility) of [original sd-webui-roop](https://github.com/s0md3v/sd-webui-roop) with a lot of improvements
|
||||||
|
|
||||||
|
> GE (Gourieff Edition), aka "NSFW-Roop"
|
||||||
|
|
||||||
This is an extension for StableDiffusion's [AUTOMATIC1111 web-ui](https://github.com/AUTOMATIC1111/stable-diffusion-webui/) that allows face-replacement in images. It is based on [Roop-GE](https://github.com/Gourieff/Roop-GE).
|
This is an extension for StableDiffusion's [AUTOMATIC1111 web-ui](https://github.com/AUTOMATIC1111/stable-diffusion-webui/) that allows face-replacement in images. It is based on [Roop-GE](https://github.com/Gourieff/Roop-GE).
|
||||||
|
|
||||||
<img src="example/demo_crop.jpg" alt="example"/>
|
<img src="example/demo_crop.jpg" alt="example"/>
|
||||||
@ -26,9 +28,15 @@ To install the extension, follow these steps:
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
1. Under "NSFW-Roop" drop-down menu, import an image containing a face.
|
1. Under "Roop-GE" drop-down menu, import an image containing a face;
|
||||||
2. Turn on the "Enable" checkbox
|
2. Turn on the "Enable" checkbox;
|
||||||
3. That's it, now the generated result will have the face you selected
|
3. That's it, now the generated result will have the face you selected.
|
||||||
|
|
||||||
|
**You can use Roop-GE with Webui API:**
|
||||||
|
1. Check the [SD Web API Wiki](https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/API) for how to use API;
|
||||||
|
2. Call `requests.get(url=f'{address}/sdapi/v1/script-info')` to find the args that Roop-GE needs;
|
||||||
|
3. Define Roop-GE script args and add like this `"alwayson_scripts": {"roop-ge":{"args":args}}` in the payload;
|
||||||
|
4. Call the API, there's an [full usage example](./example/api_example.py) in example folder.
|
||||||
|
|
||||||
### The result face is blurry
|
### The result face is blurry
|
||||||
Use the "Restore Face" option. You can also try the "Upscaler" option or for more finer control, use an upscaler from the "Extras" tab.
|
Use the "Restore Face" option. You can also try the "Upscaler" option or for more finer control, use an upscaler from the "Extras" tab.
|
||||||
|
|||||||
@ -26,13 +26,13 @@ def get_models():
|
|||||||
|
|
||||||
class FaceSwapScript(scripts.Script):
|
class FaceSwapScript(scripts.Script):
|
||||||
def title(self):
|
def title(self):
|
||||||
return f"NSFW-Roop"
|
return f"Roop-GE"
|
||||||
|
|
||||||
def show(self, is_img2img):
|
def show(self, is_img2img):
|
||||||
return scripts.AlwaysVisible
|
return scripts.AlwaysVisible
|
||||||
|
|
||||||
def ui(self, is_img2img):
|
def ui(self, is_img2img):
|
||||||
with gr.Accordion(f"NSFW-Roop {version_flag}", open=False):
|
with gr.Accordion(f"Roop-GE {version_flag}", open=False):
|
||||||
with gr.Column():
|
with gr.Column():
|
||||||
img = gr.inputs.Image(type="pil")
|
img = gr.inputs.Image(type="pil")
|
||||||
enable = gr.Checkbox(False, placeholder="enable", label="Enable")
|
enable = gr.Checkbox(False, placeholder="enable", label="Enable")
|
||||||
@ -179,7 +179,7 @@ class FaceSwapScript(scripts.Script):
|
|||||||
if self.enable:
|
if self.enable:
|
||||||
if self.source is not None:
|
if self.source is not None:
|
||||||
if isinstance(p, StableDiffusionProcessingImg2Img) and swap_in_source:
|
if isinstance(p, StableDiffusionProcessingImg2Img) and swap_in_source:
|
||||||
logger.info(f"NSFW-Roop is enabled, face index %s", self.faces_index)
|
logger.info(f"Roop-GE is enabled, face index %s", self.faces_index)
|
||||||
|
|
||||||
for i in range(len(p.init_images)):
|
for i in range(len(p.init_images)):
|
||||||
logger.info(f"Swap in source %s", i)
|
logger.info(f"Swap in source %s", i)
|
||||||
|
|||||||
@ -24,7 +24,7 @@ class ColoredFormatter(logging.Formatter):
|
|||||||
|
|
||||||
|
|
||||||
# Create a new logger
|
# Create a new logger
|
||||||
logger = logging.getLogger("NSFW-Roop")
|
logger = logging.getLogger("Roop-GE")
|
||||||
logger.propagate = False
|
logger.propagate = False
|
||||||
|
|
||||||
# Add handler if we don't have one.
|
# Add handler if we don't have one.
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
version_flag = "v0.1.0"
|
version_flag = "v0.2.0"
|
||||||
|
|
||||||
from scripts.roop_logging import logger
|
from scripts.roop_logging import logger
|
||||||
|
|
||||||
logger.info(f"NSFW-Roop {version_flag}")
|
logger.info(f"Roop-GE {version_flag}")
|
||||||
|
|||||||
@ -66,7 +66,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
|
|||||||
if upscale_options.do_restore_first:
|
if upscale_options.do_restore_first:
|
||||||
if upscale_options.face_restorer is not None:
|
if upscale_options.face_restorer is not None:
|
||||||
original_image = result_image.copy()
|
original_image = result_image.copy()
|
||||||
logger.info("1. Restore face with %s", upscale_options.face_restorer.name())
|
logger.info("Restore face with %s", upscale_options.face_restorer.name())
|
||||||
numpy_image = np.array(result_image)
|
numpy_image = np.array(result_image)
|
||||||
numpy_image = upscale_options.face_restorer.restore(numpy_image)
|
numpy_image = upscale_options.face_restorer.restore(numpy_image)
|
||||||
restored_image = Image.fromarray(numpy_image)
|
restored_image = Image.fromarray(numpy_image)
|
||||||
@ -76,7 +76,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
|
|||||||
if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
|
if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
|
||||||
original_image = result_image.copy()
|
original_image = result_image.copy()
|
||||||
logger.info(
|
logger.info(
|
||||||
"2. Upscale with %s scale = %s",
|
"Upscale with %s scale = %s",
|
||||||
upscale_options.upscaler.name,
|
upscale_options.upscaler.name,
|
||||||
upscale_options.scale,
|
upscale_options.scale,
|
||||||
)
|
)
|
||||||
@ -91,7 +91,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
|
|||||||
if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
|
if upscale_options.upscaler is not None and upscale_options.upscaler.name != "None":
|
||||||
original_image = result_image.copy()
|
original_image = result_image.copy()
|
||||||
logger.info(
|
logger.info(
|
||||||
"1. Upscale with %s scale = %s",
|
"Upscale with %s scale = %s",
|
||||||
upscale_options.upscaler.name,
|
upscale_options.upscaler.name,
|
||||||
upscale_options.scale,
|
upscale_options.scale,
|
||||||
)
|
)
|
||||||
@ -104,7 +104,7 @@ def upscale_image(image: Image, upscale_options: UpscaleOptions):
|
|||||||
)
|
)
|
||||||
if upscale_options.face_restorer is not None:
|
if upscale_options.face_restorer is not None:
|
||||||
original_image = result_image.copy()
|
original_image = result_image.copy()
|
||||||
logger.info("2. Restore face with %s", upscale_options.face_restorer.name())
|
logger.info("Restore face with %s", upscale_options.face_restorer.name())
|
||||||
numpy_image = np.array(result_image)
|
numpy_image = np.array(result_image)
|
||||||
numpy_image = upscale_options.face_restorer.restore(numpy_image)
|
numpy_image = upscale_options.face_restorer.restore(numpy_image)
|
||||||
restored_image = Image.fromarray(numpy_image)
|
restored_image = Image.fromarray(numpy_image)
|
||||||
@ -152,6 +152,20 @@ def swap_face(
|
|||||||
result_image = target_img
|
result_image = target_img
|
||||||
fn = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
|
fn = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
|
||||||
if model is not None:
|
if model is not None:
|
||||||
|
|
||||||
|
if isinstance(source_img, str): # source_img is a base64 string
|
||||||
|
import base64, io
|
||||||
|
if 'base64,' in source_img: # check if the base64 string has a data URL scheme
|
||||||
|
# split the base64 string to get the actual base64 encoded image data
|
||||||
|
base64_data = source_img.split('base64,')[-1]
|
||||||
|
# decode base64 string to bytes
|
||||||
|
img_bytes = base64.b64decode(base64_data)
|
||||||
|
else:
|
||||||
|
# if no data URL scheme, just decode
|
||||||
|
img_bytes = base64.b64decode(source_img)
|
||||||
|
|
||||||
|
source_img = Image.open(io.BytesIO(img_bytes))
|
||||||
|
|
||||||
source_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
|
source_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
|
||||||
target_img = cv2.cvtColor(np.array(target_img), cv2.COLOR_RGB2BGR)
|
target_img = cv2.cvtColor(np.array(target_img), cv2.COLOR_RGB2BGR)
|
||||||
source_face = get_face_single(source_img, face_index=source_faces_index[0])
|
source_face = get_face_single(source_img, face_index=source_faces_index[0])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user