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