mirror of
https://github.com/lllyasviel/stable-diffusion-webui-forge.git
synced 2026-04-28 18:21:48 +00:00
remove cn first
This commit is contained in:
@@ -1,60 +0,0 @@
|
||||
{
|
||||
"version": "ap10k",
|
||||
"animals": [
|
||||
[
|
||||
450.2489471435547,
|
||||
131.68504521623254,
|
||||
1.0,
|
||||
392.43172235786915,
|
||||
129.75780439004302,
|
||||
1.0,
|
||||
422.3039551638067,
|
||||
170.2298617400229,
|
||||
1.0,
|
||||
424.2311959899962,
|
||||
254.06483767926693,
|
||||
1.0,
|
||||
460.84877168759704,
|
||||
416.9166874922812,
|
||||
0.7048550844192505,
|
||||
498.42996779829264,
|
||||
295.50051544234157,
|
||||
0.742408812046051,
|
||||
513.8478944078088,
|
||||
374.5173893161118,
|
||||
0.763853132724762,
|
||||
512.884273994714,
|
||||
438.1163365803659,
|
||||
1.0,
|
||||
372.1956936828792,
|
||||
301.2822379209101,
|
||||
0.7799525856971741,
|
||||
384.7227590531111,
|
||||
381.2627322077751,
|
||||
0.8117924928665161,
|
||||
381.8318978138268,
|
||||
442.9344386458397,
|
||||
1.0,
|
||||
553.3563313446939,
|
||||
327.2999890744686,
|
||||
0.7031180262565613,
|
||||
555.2835721708834,
|
||||
375.48100972920656,
|
||||
0.6529693603515625,
|
||||
562.0289150625467,
|
||||
420.77116914466023,
|
||||
0.8226040601730347,
|
||||
409.7768897935748,
|
||||
359.09946270659566,
|
||||
0.3695080578327179,
|
||||
436.75826136022806,
|
||||
414.0258262529969,
|
||||
0.6621587872505188,
|
||||
428.08567764237523,
|
||||
422.69840997084975,
|
||||
0.552909255027771
|
||||
]
|
||||
],
|
||||
"canvas_height": 512,
|
||||
"canvas_width": 960
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import unittest
|
||||
import importlib
|
||||
import requests
|
||||
|
||||
utils = importlib.import_module(
|
||||
'extensions.sd-webui-controlnet.tests.utils', 'utils')
|
||||
|
||||
|
||||
from scripts.processor import preprocessor_filters
|
||||
|
||||
|
||||
class TestControlTypes(unittest.TestCase):
|
||||
def test_fetching_control_types(self):
|
||||
response = requests.get(utils.BASE_URL + "/controlnet/control_types")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
result = response.json()
|
||||
self.assertIn('control_types', result)
|
||||
|
||||
for control_type in preprocessor_filters:
|
||||
self.assertIn(control_type, result['control_types'])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,47 +0,0 @@
|
||||
import requests
|
||||
import unittest
|
||||
import importlib
|
||||
utils = importlib.import_module(
|
||||
'extensions.sd-webui-controlnet.tests.utils', 'utils')
|
||||
|
||||
|
||||
class TestDetectEndpointWorking(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.base_detect_args = {
|
||||
"controlnet_module": "canny",
|
||||
"controlnet_input_images": [utils.readImage("test/test_files/img2img_basic.png")],
|
||||
"controlnet_processor_res": 512,
|
||||
"controlnet_threshold_a": 0,
|
||||
"controlnet_threshold_b": 0,
|
||||
}
|
||||
|
||||
def test_detect_with_invalid_module_performed(self):
|
||||
detect_args = self.base_detect_args.copy()
|
||||
detect_args.update({
|
||||
"controlnet_module": "INVALID",
|
||||
})
|
||||
self.assertEqual(utils.detect(detect_args).status_code, 422)
|
||||
|
||||
def test_detect_with_no_input_images_performed(self):
|
||||
detect_args = self.base_detect_args.copy()
|
||||
detect_args.update({
|
||||
"controlnet_input_images": [],
|
||||
})
|
||||
self.assertEqual(utils.detect(detect_args).status_code, 422)
|
||||
|
||||
def test_detect_with_valid_args_performed(self):
|
||||
detect_args = self.base_detect_args
|
||||
response = utils.detect(detect_args)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_detect_invert(self):
|
||||
detect_args = self.base_detect_args.copy()
|
||||
detect_args["controlnet_module"] = "invert"
|
||||
response = utils.detect(detect_args)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotEqual(response.json()['images'], [""])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,3 +0,0 @@
|
||||
# Full Coverage Tests
|
||||
Tests that only run locally with all models available. Set environment variable
|
||||
`CONTROLNET_TEST_FULL_COVERAGE` to any value to enable these tests.
|
||||
@@ -1,66 +0,0 @@
|
||||
import unittest
|
||||
import pytest
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
from .template import (
|
||||
sd_version,
|
||||
StableDiffusionVersion,
|
||||
is_full_coverage,
|
||||
APITestTemplate,
|
||||
living_room_img,
|
||||
general_negative_prompt,
|
||||
)
|
||||
|
||||
base_prompt = "A modern living room"
|
||||
|
||||
general_depth_modules = [
|
||||
"depth",
|
||||
"depth_leres",
|
||||
"depth_leres++",
|
||||
"depth_anything",
|
||||
]
|
||||
hand_refiner_module = "depth_hand_refiner"
|
||||
|
||||
general_depth_models = [
|
||||
"control_sd15_depth_anything [48a4bc3a]",
|
||||
"control_v11f1p_sd15_depth [cfd03158]",
|
||||
"t2iadapter_depth_sd15v2 [3489cd37]",
|
||||
]
|
||||
hand_refiner_model = "control_sd15_inpaint_depth_hand_fp16 [09456e54]"
|
||||
|
||||
|
||||
class TestDepthFullCoverage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
if not is_full_coverage:
|
||||
pytest.skip()
|
||||
# TODO test SDXL.
|
||||
if sd_version == StableDiffusionVersion.SDXL:
|
||||
pytest.skip()
|
||||
|
||||
def test_depth(self):
|
||||
for module in general_depth_modules:
|
||||
for model in general_depth_models:
|
||||
name = f"depth_txt2img_{module}_{model}"
|
||||
with self.subTest(name=name):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
name,
|
||||
"txt2img",
|
||||
payload_overrides={
|
||||
"prompt": base_prompt,
|
||||
"negative_prompt": general_negative_prompt,
|
||||
"steps": 20,
|
||||
"width": 768,
|
||||
"height": 512,
|
||||
},
|
||||
unit_overrides={
|
||||
"module": module,
|
||||
"model": model,
|
||||
"image": living_room_img,
|
||||
},
|
||||
).exec(result_only=False)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,219 +0,0 @@
|
||||
import unittest
|
||||
import pytest
|
||||
from .template import (
|
||||
is_full_coverage,
|
||||
APITestTemplate,
|
||||
girl_img,
|
||||
mask_img,
|
||||
mask_small_img,
|
||||
)
|
||||
|
||||
|
||||
class TestInpaintFullCoverage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
if not is_full_coverage:
|
||||
pytest.skip()
|
||||
|
||||
def test_inpaint(self):
|
||||
for gen_type in ("img2img", "txt2img"):
|
||||
if gen_type == "img2img":
|
||||
payload = {
|
||||
"init_images": [girl_img],
|
||||
"mask": mask_img,
|
||||
}
|
||||
unit = {}
|
||||
else:
|
||||
payload = {}
|
||||
unit = {
|
||||
"image": {
|
||||
"image": girl_img,
|
||||
"mask": mask_img,
|
||||
}
|
||||
}
|
||||
|
||||
unit["model"] = "control_v11p_sd15_inpaint [ebff9138]"
|
||||
|
||||
for i_resize, resize_mode in enumerate(
|
||||
("Just Resize", "Crop and Resize", "Resize and Fill")
|
||||
):
|
||||
# Gen 512x768(input image size) for resize.
|
||||
if resize_mode == "Crop and Resize":
|
||||
payload["height"] = 768
|
||||
payload["width"] = 512
|
||||
|
||||
# Gen 512x512 for inner fit.
|
||||
if resize_mode == "Crop and Resize":
|
||||
payload["height"] = 512
|
||||
payload["width"] = 512
|
||||
|
||||
# Gen 768x768 for outer fit.
|
||||
if resize_mode == "Resize and Fill":
|
||||
payload["height"] = 768
|
||||
payload["width"] = 768
|
||||
|
||||
if gen_type == "img2img":
|
||||
payload["resize_mode"] = i_resize
|
||||
else:
|
||||
unit["resize_mode"] = resize_mode
|
||||
|
||||
for module in ("inpaint_only", "inpaint", "inpaint_only+lama"):
|
||||
unit["module"] = module
|
||||
|
||||
with self.subTest(
|
||||
gen_type=gen_type,
|
||||
resize_mode=resize_mode,
|
||||
module=module,
|
||||
):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
f"{gen_type}_{resize_mode}_{module}",
|
||||
gen_type,
|
||||
payload_overrides=payload,
|
||||
unit_overrides=unit,
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_inpaint_no_mask(self):
|
||||
"""Inpaint should fail if no mask is provided. Output should not contain
|
||||
ControlNet detected map."""
|
||||
for gen_type in ("img2img", "txt2img"):
|
||||
if gen_type == "img2img":
|
||||
payload = {
|
||||
"init_images": [girl_img],
|
||||
}
|
||||
unit = {}
|
||||
else:
|
||||
payload = {}
|
||||
unit = {
|
||||
"image": {
|
||||
"image": girl_img,
|
||||
}
|
||||
}
|
||||
unit["model"] = "control_v11p_sd15_inpaint [ebff9138]"
|
||||
unit["module"] = "inpaint_only"
|
||||
with self.subTest(gen_type=gen_type):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
f"{gen_type}_no_mask_fail",
|
||||
gen_type,
|
||||
payload_overrides=payload,
|
||||
unit_overrides=unit,
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_inpaint_double_mask(self):
|
||||
"""When mask is provided for both a1111 img2img input and ControlNet
|
||||
unit input, ControlNet input mask should be used."""
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
f"img2img_double_mask",
|
||||
"img2img",
|
||||
payload_overrides={
|
||||
"init_images": [girl_img],
|
||||
"mask": mask_img,
|
||||
},
|
||||
unit_overrides={
|
||||
"image": {
|
||||
"image": girl_img,
|
||||
"mask": mask_small_img,
|
||||
},
|
||||
"model": "control_v11p_sd15_inpaint [ebff9138]",
|
||||
"module": "inpaint",
|
||||
},
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_img2img_mask_on_unit(self):
|
||||
""" Usecase for inpaint_global_harmonious. """
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
f"img2img_mask_on_unit",
|
||||
"img2img",
|
||||
payload_overrides={
|
||||
"init_images": [girl_img],
|
||||
},
|
||||
unit_overrides={
|
||||
"image": {
|
||||
"image": girl_img,
|
||||
"mask": mask_small_img,
|
||||
},
|
||||
"model": "control_v11p_sd15_inpaint [ebff9138]",
|
||||
"module": "inpaint",
|
||||
},
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_outpaint_without_mask(self):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
f"img2img_outpaint_without_mask",
|
||||
"img2img",
|
||||
payload_overrides={
|
||||
"init_images": [girl_img],
|
||||
"width": 768,
|
||||
"height": 768,
|
||||
"resize_mode": 2,
|
||||
},
|
||||
unit_overrides={
|
||||
"model": "control_v11p_sd15_inpaint [ebff9138]",
|
||||
"module": "inpaint_only+lama",
|
||||
},
|
||||
).exec()
|
||||
)
|
||||
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
f"txt2img_outpaint_without_mask",
|
||||
"txt2img",
|
||||
payload_overrides={
|
||||
"width": 768,
|
||||
"height": 768,
|
||||
},
|
||||
unit_overrides={
|
||||
"model": "control_v11p_sd15_inpaint [ebff9138]",
|
||||
"module": "inpaint_only+lama",
|
||||
"image": {
|
||||
"image": girl_img,
|
||||
},
|
||||
"resize_mode": 2,
|
||||
},
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_inpaint_crop(self):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
"img2img_inpaint_crop",
|
||||
"img2img",
|
||||
payload_overrides={
|
||||
"init_images": [girl_img],
|
||||
"inpaint_full_res": True,
|
||||
"mask": mask_small_img,
|
||||
},
|
||||
unit_overrides={
|
||||
"model": "control_v11p_sd15_canny [d14c016b]",
|
||||
"module": "canny",
|
||||
"inpaint_crop_input_image": True,
|
||||
},
|
||||
).exec()
|
||||
)
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
"img2img_inpaint_no_crop",
|
||||
"img2img",
|
||||
payload_overrides={
|
||||
"init_images": [girl_img],
|
||||
"inpaint_full_res": True,
|
||||
"mask": mask_small_img,
|
||||
},
|
||||
unit_overrides={
|
||||
"model": "control_v11p_sd15_canny [d14c016b]",
|
||||
"module": "canny",
|
||||
"inpaint_crop_input_image": False,
|
||||
},
|
||||
).exec()
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,169 +0,0 @@
|
||||
import unittest
|
||||
import pytest
|
||||
from typing import NamedTuple, Optional
|
||||
|
||||
from .template import (
|
||||
sd_version,
|
||||
StableDiffusionVersion,
|
||||
is_full_coverage,
|
||||
APITestTemplate,
|
||||
portrait_imgs,
|
||||
realistic_girl_face_img,
|
||||
general_negative_prompt,
|
||||
)
|
||||
|
||||
|
||||
class AdapterSetting(NamedTuple):
|
||||
module: str
|
||||
model: str
|
||||
lora: Optional[str] = None
|
||||
|
||||
@property
|
||||
def lora_prompt(self) -> str:
|
||||
return f"<lora:{self.lora}:0.6>" if self.lora else ""
|
||||
|
||||
|
||||
# Used to fix pose for better comparison between different settings.
|
||||
openpose_unit = {
|
||||
"module": "openpose",
|
||||
"model": (
|
||||
"control_v11p_sd15_openpose [cab727d4]"
|
||||
if sd_version != StableDiffusionVersion.SDXL
|
||||
else "kohya_controllllite_xl_openpose_anime [7e5349e5]"
|
||||
),
|
||||
"image": realistic_girl_face_img,
|
||||
"weight": 0.8,
|
||||
}
|
||||
base_prompt = "1girl, simple background, (white_background: 1.2), portrait"
|
||||
negative_prompts = {
|
||||
"with_neg": general_negative_prompt,
|
||||
"no_neg": "",
|
||||
}
|
||||
|
||||
sd15_face_id = AdapterSetting(
|
||||
"ip-adapter_face_id",
|
||||
"ip-adapter-faceid_sd15 [0a1757e9]",
|
||||
"ip-adapter-faceid_sd15_lora",
|
||||
)
|
||||
sd15_face_id_plus = AdapterSetting(
|
||||
"ip-adapter_face_id_plus",
|
||||
"ip-adapter-faceid-plus_sd15 [d86a490f]",
|
||||
"ip-adapter-faceid-plus_sd15_lora",
|
||||
)
|
||||
sd15_face_id_plus_v2 = AdapterSetting(
|
||||
"ip-adapter_face_id_plus",
|
||||
"ip-adapter-faceid-plusv2_sd15 [6e14fc1a]",
|
||||
"ip-adapter-faceid-plusv2_sd15_lora",
|
||||
)
|
||||
sd15_face_id_portrait = AdapterSetting(
|
||||
"ip-adapter_face_id",
|
||||
"ip-adapter-faceid-portrait_sd15 [b2609049]",
|
||||
)
|
||||
sdxl_face_id = AdapterSetting(
|
||||
"ip-adapter_face_id",
|
||||
"ip-adapter-faceid_sdxl [59ee31a3]",
|
||||
"ip-adapter-faceid_sdxl_lora",
|
||||
)
|
||||
|
||||
|
||||
class TestIPAdapterFullCoverage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
if not is_full_coverage:
|
||||
pytest.skip()
|
||||
|
||||
if sd_version == StableDiffusionVersion.SDXL:
|
||||
self.settings = [sdxl_face_id]
|
||||
else:
|
||||
self.settings = [
|
||||
sd15_face_id,
|
||||
sd15_face_id_plus,
|
||||
sd15_face_id_plus_v2,
|
||||
sd15_face_id_portrait,
|
||||
]
|
||||
|
||||
def test_face_id(self):
|
||||
for s in self.settings:
|
||||
for n, negative_prompt in negative_prompts.items():
|
||||
name = f"{s}_{n}"
|
||||
with self.subTest(name=name):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
name,
|
||||
"txt2img",
|
||||
payload_overrides={
|
||||
"prompt": f"{base_prompt},{s.lora_prompt}",
|
||||
"negative_prompt": negative_prompt,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
},
|
||||
unit_overrides=[
|
||||
{
|
||||
"module": s.module,
|
||||
"model": s.model,
|
||||
"image": realistic_girl_face_img,
|
||||
},
|
||||
openpose_unit,
|
||||
],
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_face_id_multi_inputs(self):
|
||||
for s in self.settings:
|
||||
for n, negative_prompt in negative_prompts.items():
|
||||
name = f"multi_inputs_{s}_{n}"
|
||||
with self.subTest(name=name):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
name=name,
|
||||
gen_type="txt2img",
|
||||
payload_overrides={
|
||||
"prompt": f"{base_prompt}, {s.lora_prompt}",
|
||||
"negative_prompt": negative_prompt,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
},
|
||||
unit_overrides=[openpose_unit]
|
||||
+ [
|
||||
{
|
||||
"image": img,
|
||||
"module": s.module,
|
||||
"model": s.model,
|
||||
"weight": 1 / len(portrait_imgs),
|
||||
}
|
||||
for img in portrait_imgs
|
||||
],
|
||||
).exec()
|
||||
)
|
||||
|
||||
def test_face_id_real_multi_inputs(self):
|
||||
for s in (sd15_face_id, sd15_face_id_portrait):
|
||||
for n, negative_prompt in negative_prompts.items():
|
||||
name = f"real_multi_{s}_{n}"
|
||||
with self.subTest(name=name):
|
||||
self.assertTrue(
|
||||
APITestTemplate(
|
||||
name=name,
|
||||
gen_type="txt2img",
|
||||
payload_overrides={
|
||||
"prompt": f"{base_prompt}, {s.lora_prompt}",
|
||||
"negative_prompt": negative_prompt,
|
||||
"steps": 20,
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
},
|
||||
unit_overrides=[
|
||||
openpose_unit,
|
||||
{
|
||||
"image": [{"image": img} for img in portrait_imgs],
|
||||
"module": s.module,
|
||||
"model": s.model,
|
||||
},
|
||||
],
|
||||
).exec()
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,265 +0,0 @@
|
||||
import io
|
||||
import os
|
||||
import cv2
|
||||
import base64
|
||||
from typing import Dict, Any, List, Union, Literal
|
||||
from pathlib import Path
|
||||
import datetime
|
||||
from enum import Enum
|
||||
import numpy as np
|
||||
|
||||
import requests
|
||||
from PIL import Image
|
||||
|
||||
|
||||
PayloadOverrideType = Dict[str, Any]
|
||||
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
|
||||
test_result_dir = Path(__file__).parent / "results" / f"test_result_{timestamp}"
|
||||
test_expectation_dir = Path(__file__).parent / "expectations"
|
||||
os.makedirs(test_expectation_dir, exist_ok=True)
|
||||
resource_dir = Path(__file__).parents[2] / "images"
|
||||
|
||||
|
||||
def read_image(img_path: Path) -> str:
|
||||
img = cv2.imread(str(img_path))
|
||||
_, bytes = cv2.imencode(".png", img)
|
||||
encoded_image = base64.b64encode(bytes).decode("utf-8")
|
||||
return encoded_image
|
||||
|
||||
|
||||
def read_image_dir(img_dir: Path, suffixes=('.png', '.jpg', '.jpeg', '.webp')) -> List[str]:
|
||||
"""Try read all images in given img_dir."""
|
||||
img_dir = str(img_dir)
|
||||
images = []
|
||||
for filename in os.listdir(img_dir):
|
||||
if filename.endswith(suffixes):
|
||||
img_path = os.path.join(img_dir, filename)
|
||||
try:
|
||||
images.append(read_image(img_path))
|
||||
except IOError:
|
||||
print(f"Error opening {img_path}")
|
||||
return images
|
||||
|
||||
|
||||
girl_img = read_image(resource_dir / "1girl.png")
|
||||
mask_img = read_image(resource_dir / "mask.png")
|
||||
mask_small_img = read_image(resource_dir / "mask_small.png")
|
||||
portrait_imgs = read_image_dir(resource_dir / "portrait")
|
||||
realistic_girl_face_img = portrait_imgs[0]
|
||||
living_room_img = read_image(resource_dir / "living_room.webp")
|
||||
|
||||
general_negative_prompt = """
|
||||
(worst quality:2), (low quality:2), (normal quality:2), lowres, normal quality,
|
||||
((monochrome)), ((grayscale)), skin spots, acnes, skin blemishes, age spot,
|
||||
backlight,(ugly:1.331), (duplicate:1.331), (morbid:1.21), (mutilated:1.21),
|
||||
(tranny:1.331), mutated hands, (poorly drawn hands:1.331), blurry, (bad anatomy:1.21),
|
||||
(bad proportions:1.331), extra limbs, (missing arms:1.331), (extra legs:1.331),
|
||||
(fused fingers:1.61051), (too many fingers:1.61051), (unclear eyes:1.331), bad hands,
|
||||
missing fingers, extra digit, bad body, easynegative, nsfw"""
|
||||
|
||||
class StableDiffusionVersion(Enum):
|
||||
"""The version family of stable diffusion model."""
|
||||
|
||||
UNKNOWN = 0
|
||||
SD1x = 1
|
||||
SD2x = 2
|
||||
SDXL = 3
|
||||
|
||||
|
||||
sd_version = StableDiffusionVersion(
|
||||
int(os.environ.get("CONTROLNET_TEST_SD_VERSION", StableDiffusionVersion.SD1x.value))
|
||||
)
|
||||
|
||||
is_full_coverage = os.environ.get("CONTROLNET_TEST_FULL_COVERAGE", None) is not None
|
||||
|
||||
|
||||
class APITestTemplate:
|
||||
is_set_expectation_run = os.environ.get("CONTROLNET_SET_EXP", "True") == "True"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
gen_type: Union[Literal["img2img"], Literal["txt2img"]],
|
||||
payload_overrides: PayloadOverrideType,
|
||||
unit_overrides: Union[PayloadOverrideType, List[PayloadOverrideType]],
|
||||
):
|
||||
self.name = name
|
||||
self.url = "http://localhost:7860/sdapi/v1/" + gen_type
|
||||
self.payload = {
|
||||
**(txt2img_payload if gen_type == "txt2img" else img2img_payload),
|
||||
**payload_overrides,
|
||||
}
|
||||
unit_overrides = (
|
||||
unit_overrides
|
||||
if isinstance(unit_overrides, (list, tuple))
|
||||
else [unit_overrides]
|
||||
)
|
||||
self.payload["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
**default_unit,
|
||||
**unit_override,
|
||||
}
|
||||
for unit_override in unit_overrides
|
||||
]
|
||||
|
||||
def exec(self, result_only: bool = True) -> bool:
|
||||
if not APITestTemplate.is_set_expectation_run:
|
||||
os.makedirs(test_result_dir, exist_ok=True)
|
||||
|
||||
failed = False
|
||||
|
||||
response = requests.post(url=self.url, json=self.payload).json()
|
||||
if "images" not in response:
|
||||
print(response)
|
||||
return False
|
||||
|
||||
dest_dir = (
|
||||
test_expectation_dir
|
||||
if APITestTemplate.is_set_expectation_run
|
||||
else test_result_dir
|
||||
)
|
||||
results = response["images"][:1] if result_only else response["images"]
|
||||
for i, base64image in enumerate(results):
|
||||
img_file_name = f"{self.name}_{i}.png"
|
||||
Image.open(io.BytesIO(base64.b64decode(base64image.split(",", 1)[0]))).save(
|
||||
dest_dir / img_file_name
|
||||
)
|
||||
|
||||
if not APITestTemplate.is_set_expectation_run:
|
||||
try:
|
||||
img1 = cv2.imread(os.path.join(test_expectation_dir, img_file_name))
|
||||
img2 = cv2.imread(os.path.join(test_result_dir, img_file_name))
|
||||
except Exception as e:
|
||||
print(f"Get exception reading imgs: {e}")
|
||||
failed = True
|
||||
continue
|
||||
|
||||
if img1 is None:
|
||||
print(f"Warn: No expectation file found {img_file_name}.")
|
||||
continue
|
||||
|
||||
if not expect_same_image(
|
||||
img1,
|
||||
img2,
|
||||
diff_img_path=str(test_result_dir
|
||||
/ img_file_name.replace(".png", "_diff.png")),
|
||||
):
|
||||
failed = True
|
||||
return not failed
|
||||
|
||||
|
||||
def expect_same_image(img1, img2, diff_img_path: str) -> bool:
|
||||
# Calculate the difference between the two images
|
||||
diff = cv2.absdiff(img1, img2)
|
||||
|
||||
# Set a threshold to highlight the different pixels
|
||||
threshold = 30
|
||||
diff_highlighted = np.where(diff > threshold, 255, 0).astype(np.uint8)
|
||||
|
||||
# Assert that the two images are similar within a tolerance
|
||||
similar = np.allclose(img1, img2, rtol=0.5, atol=1)
|
||||
if not similar:
|
||||
# Save the diff_highlighted image to inspect the differences
|
||||
cv2.imwrite(diff_img_path, diff_highlighted)
|
||||
|
||||
return similar
|
||||
|
||||
|
||||
default_unit = {
|
||||
"control_mode": 0,
|
||||
"enabled": True,
|
||||
"guidance_end": 1,
|
||||
"guidance_start": 0,
|
||||
"low_vram": False,
|
||||
"pixel_perfect": True,
|
||||
"processor_res": 512,
|
||||
"resize_mode": 1,
|
||||
"threshold_a": 64,
|
||||
"threshold_b": 64,
|
||||
"weight": 1,
|
||||
}
|
||||
|
||||
img2img_payload = {
|
||||
"batch_size": 1,
|
||||
"cfg_scale": 7,
|
||||
"height": 768,
|
||||
"width": 512,
|
||||
"n_iter": 1,
|
||||
"steps": 10,
|
||||
"sampler_name": "Euler a",
|
||||
"prompt": "(masterpiece: 1.3), (highres: 1.3), best quality,",
|
||||
"negative_prompt": "",
|
||||
"seed": 42,
|
||||
"seed_enable_extras": False,
|
||||
"seed_resize_from_h": 0,
|
||||
"seed_resize_from_w": 0,
|
||||
"subseed": -1,
|
||||
"subseed_strength": 0,
|
||||
"override_settings": {},
|
||||
"override_settings_restore_afterwards": False,
|
||||
"do_not_save_grid": False,
|
||||
"do_not_save_samples": False,
|
||||
"s_churn": 0,
|
||||
"s_min_uncond": 0,
|
||||
"s_noise": 1,
|
||||
"s_tmax": None,
|
||||
"s_tmin": 0,
|
||||
"script_args": [],
|
||||
"script_name": None,
|
||||
"styles": [],
|
||||
"alwayson_scripts": {"ControlNet": {"args": [default_unit]}},
|
||||
"denoising_strength": 0.75,
|
||||
"initial_noise_multiplier": 1,
|
||||
"inpaint_full_res": 0,
|
||||
"inpaint_full_res_padding": 32,
|
||||
"inpainting_fill": 1,
|
||||
"inpainting_mask_invert": 0,
|
||||
"mask_blur_x": 4,
|
||||
"mask_blur_y": 4,
|
||||
"mask_blur": 4,
|
||||
"resize_mode": 0,
|
||||
}
|
||||
|
||||
txt2img_payload = {
|
||||
"alwayson_scripts": {"ControlNet": {"args": [default_unit]}},
|
||||
"batch_size": 1,
|
||||
"cfg_scale": 7,
|
||||
"comments": {},
|
||||
"disable_extra_networks": False,
|
||||
"do_not_save_grid": False,
|
||||
"do_not_save_samples": False,
|
||||
"enable_hr": False,
|
||||
"height": 768,
|
||||
"hr_negative_prompt": "",
|
||||
"hr_prompt": "",
|
||||
"hr_resize_x": 0,
|
||||
"hr_resize_y": 0,
|
||||
"hr_scale": 2,
|
||||
"hr_second_pass_steps": 0,
|
||||
"hr_upscaler": "Latent",
|
||||
"n_iter": 1,
|
||||
"negative_prompt": "",
|
||||
"override_settings": {},
|
||||
"override_settings_restore_afterwards": True,
|
||||
"prompt": "(masterpiece: 1.3), (highres: 1.3), best quality,",
|
||||
"restore_faces": False,
|
||||
"s_churn": 0.0,
|
||||
"s_min_uncond": 0,
|
||||
"s_noise": 1.0,
|
||||
"s_tmax": None,
|
||||
"s_tmin": 0.0,
|
||||
"sampler_name": "Euler a",
|
||||
"script_args": [],
|
||||
"script_name": None,
|
||||
"seed": 42,
|
||||
"seed_enable_extras": True,
|
||||
"seed_resize_from_h": -1,
|
||||
"seed_resize_from_w": -1,
|
||||
"steps": 10,
|
||||
"styles": [],
|
||||
"subseed": -1,
|
||||
"subseed_strength": 0,
|
||||
"tiling": False,
|
||||
"width": 512,
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
import os
|
||||
import unittest
|
||||
import importlib
|
||||
utils = importlib.import_module('extensions.sd-webui-controlnet.tests.utils', 'utils')
|
||||
import requests
|
||||
from scripts.enums import StableDiffusionVersion
|
||||
|
||||
|
||||
class TestImg2ImgWorkingBase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
sd_version = StableDiffusionVersion(int(
|
||||
os.environ.get("CONTROLNET_TEST_SD_VERSION", StableDiffusionVersion.SD1x.value)))
|
||||
self.model = utils.get_model("canny", sd_version)
|
||||
|
||||
controlnet_unit = {
|
||||
"module": "none",
|
||||
"model": self.model,
|
||||
"weight": 1.0,
|
||||
"input_image": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"mask": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"resize_mode": 1,
|
||||
"lowvram": False,
|
||||
"processor_res": 64,
|
||||
"threshold_a": 64,
|
||||
"threshold_b": 64,
|
||||
"guidance_start": 0.0,
|
||||
"guidance_end": 1.0,
|
||||
"control_mode": 0,
|
||||
}
|
||||
setup_args = {"alwayson_scripts":{"ControlNet":{"args": ([controlnet_unit] * getattr(self, 'units_count', 1))}}}
|
||||
self.setup_route(setup_args)
|
||||
|
||||
def setup_route(self, setup_args):
|
||||
self.url_img2img = "http://localhost:7860/sdapi/v1/img2img"
|
||||
self.simple_img2img = {
|
||||
"init_images": [utils.readImage("test/test_files/img2img_basic.png")],
|
||||
"resize_mode": 0,
|
||||
"denoising_strength": 0.75,
|
||||
"image_cfg_scale": 0,
|
||||
"mask_blur": 4,
|
||||
"inpainting_fill": 0,
|
||||
"inpaint_full_res": True,
|
||||
"inpaint_full_res_padding": 0,
|
||||
"inpainting_mask_invert": 0,
|
||||
"initial_noise_multiplier": 0,
|
||||
"prompt": "example prompt",
|
||||
"styles": [],
|
||||
"seed": -1,
|
||||
"subseed": -1,
|
||||
"subseed_strength": 0,
|
||||
"seed_resize_from_h": -1,
|
||||
"seed_resize_from_w": -1,
|
||||
"sampler_name": "Euler a",
|
||||
"batch_size": 1,
|
||||
"n_iter": 1,
|
||||
"steps": 3,
|
||||
"cfg_scale": 7,
|
||||
"width": 64,
|
||||
"height": 64,
|
||||
"restore_faces": False,
|
||||
"tiling": False,
|
||||
"do_not_save_samples": False,
|
||||
"do_not_save_grid": False,
|
||||
"negative_prompt": "",
|
||||
"eta": 0,
|
||||
"s_churn": 0,
|
||||
"s_tmax": 0,
|
||||
"s_tmin": 0,
|
||||
"s_noise": 1,
|
||||
"override_settings": {},
|
||||
"override_settings_restore_afterwards": True,
|
||||
"sampler_index": "Euler a",
|
||||
"include_init_images": False,
|
||||
"send_images": True,
|
||||
"save_images": False,
|
||||
"alwayson_scripts": {}
|
||||
}
|
||||
self.simple_img2img.update(setup_args)
|
||||
|
||||
def assert_status_ok(self):
|
||||
self.assertEqual(requests.post(self.url_img2img, json=self.simple_img2img).status_code, 200)
|
||||
|
||||
def test_img2img_simple_performed(self):
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_img2img_alwayson_scripts_default_units(self):
|
||||
self.units_count = 0
|
||||
self.setUp()
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_img2img_default_params(self):
|
||||
self.simple_img2img["alwayson_scripts"]["ControlNet"]["args"] = [{
|
||||
"input_image": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"model": self.model,
|
||||
}]
|
||||
self.assert_status_ok()
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,194 +0,0 @@
|
||||
{
|
||||
"people": [
|
||||
{
|
||||
"pose_keypoints_2d": [
|
||||
275.2506064884899,
|
||||
196.32469357280343,
|
||||
1,
|
||||
303.3188016469506,
|
||||
272.70982071889466,
|
||||
1,
|
||||
244.98447950024644,
|
||||
292.09994638829477,
|
||||
1,
|
||||
236.38292745027104,
|
||||
517.7037729015278,
|
||||
1,
|
||||
168.3984479500246,
|
||||
418.0022744632577,
|
||||
1,
|
||||
412.90526047751445,
|
||||
257.2121425016039,
|
||||
1,
|
||||
403.17894535813576,
|
||||
510.14290732520925,
|
||||
1,
|
||||
294.43481869004336,
|
||||
376.4781345848482,
|
||||
1,
|
||||
265.25747216047955,
|
||||
562.5137576822758,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
359.0078938961762,
|
||||
562.0711206495608,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
240.097671925037,
|
||||
184.513914838073,
|
||||
1,
|
||||
308.33409148775263,
|
||||
161.22089906296208,
|
||||
1,
|
||||
204.7558201874076,
|
||||
213.05887067565308,
|
||||
1,
|
||||
366.61934701298674,
|
||||
148.9278832878512,
|
||||
1
|
||||
],
|
||||
"hand_right_keypoints_2d": [
|
||||
168.39790150130915,
|
||||
418.0005271461072,
|
||||
1,
|
||||
181.79401055357368,
|
||||
399.3767976307846,
|
||||
1,
|
||||
184.8627576873498,
|
||||
384.75709227716266,
|
||||
1,
|
||||
198.118414869015,
|
||||
381.90007483819153,
|
||||
1,
|
||||
215.15048903799024,
|
||||
386.8527024571639,
|
||||
1,
|
||||
180.1325238303079,
|
||||
346.88417988394843,
|
||||
1,
|
||||
178.10795487568174,
|
||||
321.1018085790239,
|
||||
1,
|
||||
190.70710955474613,
|
||||
320.5669160600145,
|
||||
1,
|
||||
203.3062827659017,
|
||||
325.5456061326966,
|
||||
1,
|
||||
172.3536896669116,
|
||||
350.7525276652412,
|
||||
1,
|
||||
170.000622912838,
|
||||
325.0336533262108,
|
||||
1,
|
||||
185.70972426755964,
|
||||
323.476117950832,
|
||||
1,
|
||||
208.50724912413568,
|
||||
333.4635128502484,
|
||||
1,
|
||||
163.50256975319706,
|
||||
356.1325737292637,
|
||||
1,
|
||||
162.59147123450128,
|
||||
335.0197021116338,
|
||||
1,
|
||||
183.9828354600188,
|
||||
328.4553078224726,
|
||||
1,
|
||||
201.57171021013423,
|
||||
337.94383954551654,
|
||||
1,
|
||||
152.9805889462092,
|
||||
357.94403689402753,
|
||||
1,
|
||||
167.09651929267878,
|
||||
341.7437601311937,
|
||||
1,
|
||||
180.9402668216081,
|
||||
337.10207327446744,
|
||||
1,
|
||||
194.60028340222678,
|
||||
343.0449246874465,
|
||||
1
|
||||
],
|
||||
"hand_left_keypoints_2d": [
|
||||
294.4393772120137,
|
||||
376.476024395234,
|
||||
1,
|
||||
271.70933825161165,
|
||||
384.48117305399165,
|
||||
1,
|
||||
257.2452829806548,
|
||||
374.58948859472207,
|
||||
1,
|
||||
238.26122936397638,
|
||||
375.2887100029166,
|
||||
1,
|
||||
219.89983184668415,
|
||||
382.69322630254595,
|
||||
1,
|
||||
263.0323651487124,
|
||||
320.1279349241104,
|
||||
1,
|
||||
246.94602107917282,
|
||||
309.8099960810156,
|
||||
1,
|
||||
233.73717716804694,
|
||||
314.1485136789638,
|
||||
1,
|
||||
224.27755744411303,
|
||||
322.7892154545116,
|
||||
1,
|
||||
264.97558037166135,
|
||||
334.6319791090978,
|
||||
1,
|
||||
254.35598193615226,
|
||||
315.5629746257517,
|
||||
1,
|
||||
238.25810853722876,
|
||||
321.2812182403252,
|
||||
1,
|
||||
223.57727818251382,
|
||||
328.39525394113423,
|
||||
1,
|
||||
278.15831452661644,
|
||||
337.1533682086847,
|
||||
1,
|
||||
265.12624946042416,
|
||||
323.3619430418993,
|
||||
1,
|
||||
250.5919197031302,
|
||||
325.30525908324694,
|
||||
1,
|
||||
235.2500911122877,
|
||||
332.6721359855453,
|
||||
1,
|
||||
285.9427695830851,
|
||||
341.50671458478496,
|
||||
1,
|
||||
274.50497773130155,
|
||||
333.1376809270594,
|
||||
1,
|
||||
261.49768784257105,
|
||||
328.7012203257942,
|
||||
1,
|
||||
248.90495501067193,
|
||||
332.0535195828255,
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"canvas_width": 512,
|
||||
"canvas_height": 512
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import requests
|
||||
import unittest
|
||||
import importlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils")
|
||||
|
||||
|
||||
def render(poses):
|
||||
return requests.post(
|
||||
utils.BASE_URL + "/controlnet/render_openpose_json", json=poses
|
||||
).json()
|
||||
|
||||
|
||||
with open(Path(__file__).parent / "pose.json", "r") as f:
|
||||
pose = json.load(f)
|
||||
|
||||
|
||||
with open(Path(__file__).parent / "animal_pose.json", "r") as f:
|
||||
animal_pose = json.load(f)
|
||||
|
||||
|
||||
class TestDetectEndpointWorking(unittest.TestCase):
|
||||
def test_render_single(self):
|
||||
res = render([pose])
|
||||
self.assertEqual(res["info"], "Success")
|
||||
self.assertEqual(len(res["images"]), 1)
|
||||
|
||||
def test_render_multiple(self):
|
||||
res = render([pose, pose])
|
||||
self.assertEqual(res["info"], "Success")
|
||||
self.assertEqual(len(res["images"]), 2)
|
||||
|
||||
def test_render_no_pose(self):
|
||||
res = render([])
|
||||
self.assertNotEqual(res["info"], "Success")
|
||||
|
||||
def test_render_invalid_pose(self):
|
||||
res = render([{"foo": 10, "bar": 100}])
|
||||
self.assertNotIn("info", res)
|
||||
self.assertNotIn("images", res)
|
||||
|
||||
def test_render_animals(self):
|
||||
res = render([animal_pose])
|
||||
self.assertEqual(res["info"], "Success")
|
||||
self.assertEqual(len(res["images"]), 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,286 +0,0 @@
|
||||
import os
|
||||
import unittest
|
||||
import requests
|
||||
import importlib
|
||||
|
||||
utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils")
|
||||
from scripts.enums import StableDiffusionVersion
|
||||
from modules import shared
|
||||
|
||||
|
||||
class TestAlwaysonTxt2ImgWorking(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.sd_version = StableDiffusionVersion(
|
||||
int(
|
||||
os.environ.get(
|
||||
"CONTROLNET_TEST_SD_VERSION", StableDiffusionVersion.SD1x.value
|
||||
)
|
||||
)
|
||||
)
|
||||
self.model = utils.get_model("canny", self.sd_version)
|
||||
|
||||
controlnet_unit = {
|
||||
"enabled": True,
|
||||
"module": "none",
|
||||
"model": self.model,
|
||||
"weight": 1.0,
|
||||
"image": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"mask": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"resize_mode": 1,
|
||||
"lowvram": False,
|
||||
"processor_res": 64,
|
||||
"threshold_a": 64,
|
||||
"threshold_b": 64,
|
||||
"guidance_start": 0.0,
|
||||
"guidance_end": 1.0,
|
||||
"control_mode": 0,
|
||||
"pixel_perfect": False,
|
||||
}
|
||||
setup_args = [controlnet_unit] * getattr(self, "units_count", 1)
|
||||
self.setup_route(setup_args)
|
||||
|
||||
def setup_route(self, setup_args):
|
||||
self.url_txt2img = "http://localhost:7860/sdapi/v1/txt2img"
|
||||
self.simple_txt2img = {
|
||||
"enable_hr": False,
|
||||
"denoising_strength": 0,
|
||||
"firstphase_width": 0,
|
||||
"firstphase_height": 0,
|
||||
"prompt": "example prompt",
|
||||
"styles": [],
|
||||
"seed": -1,
|
||||
"subseed": -1,
|
||||
"subseed_strength": 0,
|
||||
"seed_resize_from_h": -1,
|
||||
"seed_resize_from_w": -1,
|
||||
"batch_size": 1,
|
||||
"n_iter": 1,
|
||||
"steps": 3,
|
||||
"cfg_scale": 7,
|
||||
"width": 64,
|
||||
"height": 64,
|
||||
"restore_faces": False,
|
||||
"tiling": False,
|
||||
"negative_prompt": "",
|
||||
"eta": 0,
|
||||
"s_churn": 0,
|
||||
"s_tmax": 0,
|
||||
"s_tmin": 0,
|
||||
"s_noise": 1,
|
||||
"sampler_index": "Euler a",
|
||||
"alwayson_scripts": {},
|
||||
}
|
||||
self.setup_controlnet_params(setup_args)
|
||||
|
||||
def setup_controlnet_params(self, setup_args):
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"] = {"args": setup_args}
|
||||
|
||||
def assert_status_ok(self, msg=None, expected_image_num=None):
|
||||
msg = ("" if msg is None else msg) + f"\nPayload:\n{self.simple_txt2img}"
|
||||
|
||||
resp = requests.post(self.url_txt2img, json=self.simple_txt2img)
|
||||
self.assertEqual(resp.status_code, 200, msg)
|
||||
# Note: Exception/error in ControlNet code likely will cause hook failure, which further leads
|
||||
# to detected map not being appended at the end of response image array.
|
||||
data = resp.json()
|
||||
if expected_image_num is None:
|
||||
expected_image_num = self.simple_txt2img["n_iter"] * self.simple_txt2img[
|
||||
"batch_size"
|
||||
] + min(
|
||||
sum(
|
||||
[
|
||||
unit.get("save_detected_map", True)
|
||||
for unit in self.simple_txt2img["alwayson_scripts"]["ControlNet"][
|
||||
"args"
|
||||
]
|
||||
]
|
||||
),
|
||||
shared.opts.data.get("control_net_unit_count", 3),
|
||||
)
|
||||
self.assertEqual(len(data["images"]), expected_image_num, msg)
|
||||
|
||||
def test_txt2img_simple_performed(self):
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_txt2img_alwayson_scripts_default_units(self):
|
||||
self.units_count = 0
|
||||
self.setUp()
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_txt2img_multiple_batches_performed(self):
|
||||
self.simple_txt2img["n_iter"] = 2
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_txt2img_batch_performed(self):
|
||||
self.simple_txt2img["batch_size"] = 2
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_txt2img_2_units(self):
|
||||
self.units_count = 2
|
||||
self.setUp()
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_txt2img_8_units(self):
|
||||
self.units_count = 8
|
||||
self.setUp()
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_txt2img_default_params(self):
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
"input_image": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"model": self.model,
|
||||
}
|
||||
]
|
||||
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_call_with_preprocessors(self):
|
||||
available_modules = utils.get_modules()
|
||||
available_modules_list = available_modules.get("module_list", [])
|
||||
available_modules_detail = available_modules.get("module_detail", {})
|
||||
for module in ["depth", "openpose_full"]:
|
||||
assert module in available_modules_list, f"Failed to find {module}."
|
||||
assert (
|
||||
module in available_modules_detail
|
||||
), f"Failed to find {module}'s detail."
|
||||
with self.subTest(module=module):
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
"input_image": utils.readImage(
|
||||
"test/test_files/img2img_basic.png"
|
||||
),
|
||||
"model": self.model,
|
||||
"module": module,
|
||||
}
|
||||
]
|
||||
self.assert_status_ok(f"Running preprocessor module: {module}")
|
||||
|
||||
def test_call_invalid_params(self):
|
||||
for param in ("processor_res", "threshold_a", "threshold_b"):
|
||||
with self.subTest(param=param):
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
"input_image": utils.readImage(
|
||||
"test/test_files/img2img_basic.png"
|
||||
),
|
||||
"model": self.model,
|
||||
param: -1,
|
||||
}
|
||||
]
|
||||
self.assert_status_ok(f"Run with {param} = -1.")
|
||||
|
||||
def test_save_detected_map(self):
|
||||
for save_map in (True, False):
|
||||
with self.subTest(save_map=save_map):
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
"input_image": utils.readImage(
|
||||
"test/test_files/img2img_basic.png"
|
||||
),
|
||||
"model": self.model,
|
||||
"module": "depth",
|
||||
"save_detected_map": save_map,
|
||||
}
|
||||
]
|
||||
|
||||
resp = requests.post(self.url_txt2img, json=self.simple_txt2img).json()
|
||||
self.assertEqual(2 if save_map else 1, len(resp["images"]))
|
||||
|
||||
def run_test_unit(
|
||||
self, module: str, model: str, sd_version: StableDiffusionVersion
|
||||
) -> None:
|
||||
if self.sd_version != sd_version:
|
||||
return
|
||||
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
"input_image": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"model": utils.get_model(model, sd_version),
|
||||
"module": module,
|
||||
}
|
||||
]
|
||||
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_ip_adapter_face(self):
|
||||
self.run_test_unit(
|
||||
"ip-adapter_clip_sdxl_plus_vith",
|
||||
"ip-adapter-plus-face_sdxl_vit-h",
|
||||
StableDiffusionVersion.SDXL,
|
||||
)
|
||||
self.run_test_unit(
|
||||
"ip-adapter_clip_sd15",
|
||||
"ip-adapter-plus-face_sd15",
|
||||
StableDiffusionVersion.SD1x,
|
||||
)
|
||||
|
||||
def test_ip_adapter_fullface(self):
|
||||
self.run_test_unit(
|
||||
"ip-adapter_clip_sd15",
|
||||
"ip-adapter-full-face_sd15",
|
||||
StableDiffusionVersion.SD1x,
|
||||
)
|
||||
|
||||
def test_control_lora(self):
|
||||
self.run_test_unit("canny", "sai_xl_canny_128lora", StableDiffusionVersion.SDXL)
|
||||
self.run_test_unit("canny", "control_lora_rank128_v11p_sd15_canny", StableDiffusionVersion.SD1x)
|
||||
|
||||
def test_control_lllite(self):
|
||||
self.run_test_unit(
|
||||
"canny", "kohya_controllllite_xl_canny", StableDiffusionVersion.SDXL
|
||||
)
|
||||
|
||||
def test_diffusers_controlnet(self):
|
||||
self.run_test_unit(
|
||||
"canny", "diffusers_xl_canny_small", StableDiffusionVersion.SDXL
|
||||
)
|
||||
|
||||
def test_t2i_adapter(self):
|
||||
self.run_test_unit(
|
||||
"canny", "t2iadapter_canny_sd15v2", StableDiffusionVersion.SD1x
|
||||
)
|
||||
self.run_test_unit("canny", "t2i-adapter_xl_canny", StableDiffusionVersion.SDXL)
|
||||
|
||||
def test_reference(self):
|
||||
self.run_test_unit("reference_only", "None", StableDiffusionVersion.SD1x)
|
||||
self.run_test_unit("reference_only", "None", StableDiffusionVersion.SDXL)
|
||||
|
||||
def test_unrecognized_param(self):
|
||||
unit = self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"][0]
|
||||
unit["foo"] = True
|
||||
unit["is_ui"] = False
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_default_model(self):
|
||||
# Model "None" should be used when model is not specified in the payload.
|
||||
self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"] = [
|
||||
{
|
||||
"input_image": utils.readImage("test/test_files/img2img_basic.png"),
|
||||
"module": "reference_only",
|
||||
}
|
||||
]
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_advanced_weighting(self):
|
||||
unit = self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"][0]
|
||||
unit["advanced_weighting"] = [0.75] * self.sd_version.controlnet_layer_num()
|
||||
self.assert_status_ok()
|
||||
|
||||
def test_hr_option(self):
|
||||
# In non-hr run, hr_option should be ignored.
|
||||
unit = self.simple_txt2img["alwayson_scripts"]["ControlNet"]["args"][0]
|
||||
unit["hr_option"] = "High res only"
|
||||
self.assert_status_ok(expected_image_num=2)
|
||||
|
||||
# Hr run.
|
||||
self.simple_txt2img["enable_hr"] = True
|
||||
self.assert_status_ok(expected_image_num=3)
|
||||
|
||||
self.simple_txt2img["enable_hr"] = True
|
||||
unit["hr_option"] = "HiResFixOption.BOTH"
|
||||
self.assert_status_ok(expected_image_num=3)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user