mirror of https://github.com/Bing-su/adetailer.git
commit
3a599f5d46
|
|
@ -3,6 +3,7 @@ on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- "v*"
|
- "v*"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
|
@ -17,10 +18,11 @@ jobs:
|
||||||
needs: [test]
|
needs: [test]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
|
- uses: astral-sh/setup-uv@v7
|
||||||
|
|
||||||
- name: Build wheel
|
- name: Build wheel
|
||||||
run: pipx run build
|
run: uv build
|
||||||
|
|
||||||
- name: Publish to PyPI
|
- name: Publish to PyPI
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ jobs:
|
||||||
stale:
|
stale:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
days-before-stale: 17
|
days-before-stale: 17
|
||||||
days-before-close: 3
|
days-before-close: 3
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- "adetailer/**.py"
|
- "adetailer/**.py"
|
||||||
|
- ".github/workflows/test.yml"
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * 0"
|
- cron: "0 0 * * 0"
|
||||||
|
|
||||||
|
|
@ -13,18 +15,21 @@ jobs:
|
||||||
name: Test on python ${{ matrix.python-version }}
|
name: Test on python ${{ matrix.python-version }}
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python-version:
|
python-version:
|
||||||
- "3.10"
|
- "3.10"
|
||||||
- "3.11"
|
- "3.11"
|
||||||
- "3.12"
|
- "3.12"
|
||||||
|
- "3.13"
|
||||||
|
- "3.14"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- uses: astral-sh/setup-uv@v5
|
- uses: astral-sh/setup-uv@v7
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: uv run --all-extras pytest -v
|
run: uv run --all-extras --with 'git+https://github.com/ultralytics/CLIP.git' pytest -v
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ exclude: ^modules/
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v5.0.0
|
rev: v6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
args: [--maxkb=100]
|
args: [--maxkb=100]
|
||||||
|
|
@ -19,13 +19,13 @@ repos:
|
||||||
- id: mixed-line-ending
|
- id: mixed-line-ending
|
||||||
|
|
||||||
- repo: https://github.com/rbubley/mirrors-prettier
|
- repo: https://github.com/rbubley/mirrors-prettier
|
||||||
rev: v3.5.3
|
rev: v3.8.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.9.9
|
rev: v0.15.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff-check
|
||||||
args: [--fix, --exit-non-zero-on-fix]
|
args: [--fix, --exit-non-zero-on-fix]
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"ms-python.vscode-pylance",
|
"ms-python.vscode-pylance",
|
||||||
"ms-python.black-formatter",
|
|
||||||
"kevinrose.vsc-python-indent",
|
"kevinrose.vsc-python-indent",
|
||||||
"charliermarsh.ruff",
|
"charliermarsh.ruff",
|
||||||
"shardulm94.trailing-spaces"
|
"shardulm94.trailing-spaces"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-02-05
|
||||||
|
|
||||||
|
- v26.2.0
|
||||||
|
- segmentation 모델의 마스크 dtype이 uint8로 변경된 것에 대응
|
||||||
|
|
||||||
## 2025-03-10
|
## 2025-03-10
|
||||||
|
|
||||||
- v25.3.0
|
- v25.3.0
|
||||||
|
|
@ -121,7 +126,6 @@
|
||||||
- YOLO World 모델 추가: 가장 큰 yolov8x-world.pt 모델만 기본적으로 선택할 수 있게 함.
|
- YOLO World 모델 추가: 가장 큰 yolov8x-world.pt 모델만 기본적으로 선택할 수 있게 함.
|
||||||
- lllyasviel/stable-diffusion-webui-forge에서 컨트롤넷을 사용가능하게 함 (PR #517)
|
- lllyasviel/stable-diffusion-webui-forge에서 컨트롤넷을 사용가능하게 함 (PR #517)
|
||||||
- 기본 스크립트 목록에 soft_inpainting 추가 (https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14208)
|
- 기본 스크립트 목록에 soft_inpainting 추가 (https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/14208)
|
||||||
|
|
||||||
- 기존에 설치한 사람에게 소급적용되지는 않음
|
- 기존에 설치한 사람에게 소급적용되지는 않음
|
||||||
|
|
||||||
- 감지모델에 대한 간단한 pytest 추가함
|
- 감지모델에 대한 간단한 pytest 추가함
|
||||||
|
|
@ -348,7 +352,6 @@
|
||||||
- `ad_inpaint_full_res` → `ad_inpaint_only_masked`
|
- `ad_inpaint_full_res` → `ad_inpaint_only_masked`
|
||||||
- `ad_inpaint_full_res_padding` → `ad_inpaint_only_masked_padding`
|
- `ad_inpaint_full_res_padding` → `ad_inpaint_only_masked_padding`
|
||||||
- mediapipe face mesh 모델 추가
|
- mediapipe face mesh 모델 추가
|
||||||
|
|
||||||
- mediapipe 최소 버전 `0.10.0`
|
- mediapipe 최소 버전 `0.10.0`
|
||||||
|
|
||||||
- rich traceback 제거함
|
- rich traceback 제거함
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from __future__ import annotations # noqa: A005
|
from __future__ import annotations
|
||||||
|
|
||||||
import io
|
import io
|
||||||
import platform
|
import platform
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
__version__ = "25.3.0"
|
__version__ = "26.2.0"
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,12 @@ def mask_to_pil(masks: torch.Tensor, shape: tuple[int, int]) -> list[Image.Image
|
||||||
"""
|
"""
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
masks: torch.Tensor, dtype=torch.float32, shape=(N, H, W).
|
masks: torch.Tensor, dtype=torch.float32 or torch.uint8, shape=(N, H, W).
|
||||||
The device can be CUDA, but `to_pil_image` takes care of that.
|
uint8 tensor is expected to have values 0 or 1 (not 0-255).
|
||||||
|
|
||||||
shape: tuple[int, int]
|
shape: tuple[int, int]
|
||||||
(W, H) of the original image
|
(W, H) of the original image
|
||||||
"""
|
"""
|
||||||
|
masks = masks.float()
|
||||||
n = masks.shape[0]
|
n = masks.shape[0]
|
||||||
return [to_pil_image(masks[i], mode="L").resize(shape) for i in range(n)]
|
return [to_pil_image(masks[i], mode="L").resize(shape) for i in range(n)]
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ def install():
|
||||||
deps = [
|
deps = [
|
||||||
# requirements
|
# requirements
|
||||||
("ultralytics", "8.3.75", None),
|
("ultralytics", "8.3.75", None),
|
||||||
("mediapipe", "0.10.13", "0.10.15"),
|
("mediapipe", "0.10.13", None),
|
||||||
("rich", "13.0.0", None),
|
("rich", "13.0.0", None),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
[project]
|
[project]
|
||||||
name = "adetailer"
|
name = "adetailer"
|
||||||
description = "An object detection and auto-mask extension for stable diffusion webui."
|
description = "An object detection and auto-mask extension for stable diffusion webui."
|
||||||
authors = [{ name = "dowon", email = "ks2515@naver.com" }]
|
|
||||||
requires-python = ">=3.9"
|
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.9"
|
||||||
license = { text = "AGPL-3.0" }
|
license = { text = "AGPL-3.0" }
|
||||||
dependencies = [
|
authors = [{ name = "dowon", email = "ks2515@naver.com" }]
|
||||||
"ultralytics>=8.2",
|
|
||||||
"mediapipe>=0.10.13",
|
|
||||||
"pydantic<3",
|
|
||||||
"rich>=13",
|
|
||||||
"huggingface_hub",
|
|
||||||
]
|
|
||||||
keywords = [
|
keywords = [
|
||||||
"stable-diffusion",
|
"adetailer",
|
||||||
"stable-diffusion-webui",
|
"stable-diffusion",
|
||||||
"adetailer",
|
"stable-diffusion-webui",
|
||||||
"ultralytics",
|
"ultralytics",
|
||||||
]
|
]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"License :: OSI Approved :: GNU Affero General Public License v3",
|
"License :: OSI Approved :: GNU Affero General Public License v3",
|
||||||
"Topic :: Scientific/Engineering :: Image Recognition",
|
"Topic :: Scientific/Engineering :: Image Recognition",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"huggingface-hub",
|
||||||
|
"mediapipe>=0.10.13",
|
||||||
|
"pydantic<3",
|
||||||
|
"rich>=13",
|
||||||
|
"ultralytics>=8.2",
|
||||||
]
|
]
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ dynamic = ["version"]
|
||||||
repository = "https://github.com/Bing-su/adetailer"
|
repository = "https://github.com/Bing-su/adetailer"
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = ["ruff", "pre-commit", "devtools"]
|
dev = ["devtools"]
|
||||||
test = ["pytest", "hypothesis"]
|
test = ["pytest", "hypothesis"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
@ -48,32 +48,33 @@ extend-exclude = ["modules"]
|
||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
select = [
|
select = [
|
||||||
"A",
|
"A",
|
||||||
"B",
|
"B",
|
||||||
"C4",
|
"C4",
|
||||||
"C90",
|
"C90",
|
||||||
"E",
|
"E",
|
||||||
"EM",
|
"EM",
|
||||||
"F",
|
"F",
|
||||||
"FA",
|
"FA",
|
||||||
"I001",
|
"I001",
|
||||||
"ISC",
|
"ISC",
|
||||||
"N",
|
"N",
|
||||||
"PD",
|
"PD",
|
||||||
"PERF",
|
"PERF",
|
||||||
"PL",
|
"PL",
|
||||||
"PIE",
|
"PLC",
|
||||||
"PT",
|
"PIE",
|
||||||
"PTH",
|
"PT",
|
||||||
"RET",
|
"PTH",
|
||||||
"RUF",
|
"RET",
|
||||||
"SIM",
|
"RUF",
|
||||||
"T20",
|
"SIM",
|
||||||
"TRY",
|
"T20",
|
||||||
"UP",
|
"TRY",
|
||||||
"W",
|
"UP",
|
||||||
|
"W",
|
||||||
]
|
]
|
||||||
ignore = ["B905", "E501", "PLR2004", "PLW0603"]
|
ignore = ["B905", "E501", "PLC0415", "PLR2004", "PLW0603"]
|
||||||
unfixable = ["F401"]
|
unfixable = ["F401"]
|
||||||
|
|
||||||
[tool.ruff.lint.isort]
|
[tool.ruff.lint.isort]
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
|
import torch
|
||||||
from huggingface_hub import hf_hub_download
|
from huggingface_hub import hf_hub_download
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from adetailer.ultralytics import ultralytics_predict
|
from adetailer.ultralytics import mask_to_pil, ultralytics_predict
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|
@ -60,3 +62,35 @@ def test_yolo_world(sample_image2: Image.Image, klass: str):
|
||||||
assert len(result.masks) > 0
|
assert len(result.masks) > 0
|
||||||
assert len(result.confidences) > 0
|
assert len(result.confidences) > 0
|
||||||
assert len(result.bboxes) == len(result.masks) == len(result.confidences)
|
assert len(result.bboxes) == len(result.masks) == len(result.confidences)
|
||||||
|
|
||||||
|
|
||||||
|
class TestMaskToPil:
|
||||||
|
def test_mask_to_pil_float32(self):
|
||||||
|
mask = torch.tensor([[[0.0, 1.0], [0.0, 1.0]]], dtype=torch.float32)
|
||||||
|
imgs = mask_to_pil(mask, shape=(2, 2))
|
||||||
|
|
||||||
|
assert len(imgs) == 1
|
||||||
|
img = imgs[0]
|
||||||
|
assert isinstance(img, Image.Image)
|
||||||
|
|
||||||
|
arr = np.array(img)
|
||||||
|
assert arr.shape == (2, 2)
|
||||||
|
assert arr.dtype == np.uint8
|
||||||
|
|
||||||
|
expected = np.array([[0, 255], [0, 255]], dtype=np.uint8)
|
||||||
|
np.testing.assert_array_equal(arr, expected)
|
||||||
|
|
||||||
|
def test_mask_to_pil_uint8(self):
|
||||||
|
mask = torch.tensor([[[0, 1], [0, 1]]], dtype=torch.uint8)
|
||||||
|
imgs = mask_to_pil(mask, shape=(2, 2))
|
||||||
|
|
||||||
|
assert len(imgs) == 1
|
||||||
|
img = imgs[0]
|
||||||
|
assert isinstance(img, Image.Image)
|
||||||
|
|
||||||
|
arr = np.array(img)
|
||||||
|
assert arr.shape == (2, 2)
|
||||||
|
assert arr.dtype == np.uint8
|
||||||
|
|
||||||
|
expected = np.array([[0, 255], [0, 255]], dtype=np.uint8)
|
||||||
|
np.testing.assert_array_equal(arr, expected)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue