Implement BiRefNet and HAT Sharper models with background removal capabilities

- Added validation documentation for AI model tiers.
- Introduced `background.py` for background removal logic, including inference functions for alpha and foreground extraction.
- Created `onnx_birefnet.py` to handle BiRefNet model sessions and alpha inference.
- Developed tests for background models, ensuring proper dispatch and session reuse.
- Added tests for BiRefNet ONNX model to validate alpha output and error handling for invalid values.
- Implemented model export scripts for BiRefNet and HAT Sharper, ensuring proper weight compression and licensing.
- Created `deform_sampling.py` for deformable convolution operations used in BiRefNet.
- Added utility functions for compressing ONNX weights without altering graph arithmetic.
- Introduced a reference plane node for depth field adjustments in geometry processing.
This commit is contained in:
2026-09-10 20:50:44 +08:00
parent 8ae3c1d5b7
commit e8129fe495
70 changed files with 1890 additions and 1208 deletions

View File

@@ -31,7 +31,7 @@ class AiSetupTest(BlenderTestCase):
calls,
[
("download-model", {"model": "MOGE2_VITS_NORMAL"}),
("download-model", {"model": "BEN2_BASE"}),
("download-model", {"model": "BIREFNET_LITE"}),
(
"download-model",
{"model": "REALESRGAN_GENERAL_WDN_X4V3"},
@@ -50,9 +50,9 @@ class AiSetupTest(BlenderTestCase):
with self.assertRaisesRegex(
RuntimeError,
(
"MoGe-2 ViT-S Normal: network unavailable; "
"BEN2 Base: network unavailable; "
"Real-ESRGAN General WDN x4v3: network unavailable"
"Fast \\| MoGe-2 ViT-S Normal: network unavailable; "
"Fast \\| BiRefNet Lite: network unavailable; "
"Fast \\| Real-ESRGAN General WDN x4v3: network unavailable"
),
):
self.runtime.post_install(SimpleNamespace(request=request))
@@ -61,7 +61,7 @@ class AiSetupTest(BlenderTestCase):
calls,
[
"MOGE2_VITS_NORMAL",
"BEN2_BASE",
"BIREFNET_LITE",
"REALESRGAN_GENERAL_WDN_X4V3",
],
)
@@ -77,7 +77,7 @@ class AiSetupTest(BlenderTestCase):
{
"models": [
"MOGE2_VITS_NORMAL",
"BEN2_BASE",
"BIREFNET_LITE",
"REALESRGAN_GENERAL_WDN_X4V3",
]
},
@@ -93,7 +93,7 @@ class AiSetupTest(BlenderTestCase):
"model_catalog",
return_value=(
{"key": "MOGE2_VITS_NORMAL", "ready": True},
{"key": "BEN2_BASE", "ready": False},
{"key": "BIREFNET_LITE", "ready": False},
{
"key": "REALESRGAN_GENERAL_WDN_X4V3",
"ready": True,
@@ -103,7 +103,7 @@ class AiSetupTest(BlenderTestCase):
):
status = properties.ai_status()
self.assertTrue(status["environment_ready"])
self.assertEqual(status["missing_models"], ("BEN2_BASE",))
self.assertEqual(status["missing_models"], ("BIREFNET_LITE",))
self.assertFalse(status["ready"])
self.assertEqual(properties.ai_setup_label(status), "Download Required Models…")
@@ -114,7 +114,7 @@ class AiSetupTest(BlenderTestCase):
"model_catalog",
return_value=tuple(
{"key": key, "ready": True}
for key in properties.REQUIRED_MODEL_KEYS
for key in properties.shared_model_catalog.DEFAULT_MODEL_KEYS
),
),
):
@@ -148,7 +148,7 @@ class AiSetupTest(BlenderTestCase):
"ai_status",
return_value={
"environment_ready": False,
"missing_models": ("MOGE2_VITS_NORMAL", "BEN2_BASE"),
"missing_models": ("MOGE2_VITS_NORMAL", "BIREFNET_LITE"),
"ready": False,
},
):
@@ -159,7 +159,7 @@ class AiSetupTest(BlenderTestCase):
"ai_status",
return_value={
"environment_ready": True,
"missing_models": ("BEN2_BASE",),
"missing_models": ("BIREFNET_LITE",),
"ready": False,
},
):
@@ -185,13 +185,14 @@ class AiSetupTest(BlenderTestCase):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
moge = root / "models" / "moge-2-vits-normal-onnx"
ben2 = root / "models" / "BEN2-ONNX" / "onnx"
lite = root / "models" / "birefnet-lite"
wdn = root / "models" / "realesr-general-wdn-x4v3"
moge.mkdir(parents=True)
ben2.mkdir(parents=True)
lite.mkdir(parents=True)
wdn.mkdir(parents=True)
(moge / "model.onnx").touch()
(ben2 / "model_fp16.onnx").touch()
(lite / "model.onnx").touch()
(lite / "LICENSE.txt").touch()
(wdn / "realesr-general-wdn-x4v3.onnx").touch()
with (