Spaces:
No application file
No application file
Upload 2 files
Browse files- tagger導入手順書(Ubuntu系Linux用).md +42 -0
- tagging.py +79 -0
tagger導入手順書(Ubuntu系Linux用).md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# tagger導入手順書(Ubuntu系Linux用)
|
| 2 |
+
|
| 3 |
+
## 1. 必要なパッケージのインストール
|
| 4 |
+
|
| 5 |
+
```bash
|
| 6 |
+
sudo apt update
|
| 7 |
+
sudo apt install python3-pip python3-venv git
|
| 8 |
+
```
|
| 9 |
+
|
| 10 |
+
## 2. リポジトリのクローンと環境設定
|
| 11 |
+
|
| 12 |
+
```bash
|
| 13 |
+
git clone https://github.com/ryogrid/anime-illust-image-searcher.git
|
| 14 |
+
cd anime-illust-image-searcher
|
| 15 |
+
python3 -m venv venv
|
| 16 |
+
source venv/bin/activate
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
## 3. 必要なPythonライブラリのインストール
|
| 20 |
+
|
| 21 |
+
```bash
|
| 22 |
+
pip install torch timm pillow numpy
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
## 4. タグ定義ファイルのダウンロード
|
| 26 |
+
|
| 27 |
+
```bash
|
| 28 |
+
wget https://huggingface.co/SmilingWolf/wd-eva02-large-tagger-v3/raw/main/selected_tags.csv
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
## 5. 動作確認
|
| 32 |
+
|
| 33 |
+
```bash
|
| 34 |
+
python tagging.py --dir ./your_image_directory/
|
| 35 |
+
```
|
| 36 |
+
|
| 37 |
+
## 注意事項
|
| 38 |
+
|
| 39 |
+
- 仮想環境を再度使用する場合は `source venv/bin/activate` を実行してください
|
| 40 |
+
- GPUを使用する場合は、CUDAとcuDNNのインストールが別途必要です
|
| 41 |
+
- 処理速度は1ファイルあたり約10-15秒かかります
|
| 42 |
+
- 出力結果は `tags-wd-tagger.txt` に保存されます
|
tagging.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import argparse
|
| 3 |
+
from PIL import Image
|
| 4 |
+
import torch
|
| 5 |
+
import timm
|
| 6 |
+
import glob
|
| 7 |
+
from datetime import datetime
|
| 8 |
+
import time
|
| 9 |
+
import numpy as np
|
| 10 |
+
import csv
|
| 11 |
+
|
| 12 |
+
def get_image_files(directory):
|
| 13 |
+
"""画像ファイルを再帰的に取得"""
|
| 14 |
+
extensions = ('*.jpg', '*.jpeg', '*.png', '*.gif', '*.webp')
|
| 15 |
+
image_files = []
|
| 16 |
+
for ext in extensions:
|
| 17 |
+
image_files.extend(glob.glob(os.path.join(directory, '**', ext), recursive=True))
|
| 18 |
+
return image_files
|
| 19 |
+
|
| 20 |
+
def process_image(image_path, model, size=448):
|
| 21 |
+
"""画像からタグを抽出"""
|
| 22 |
+
try:
|
| 23 |
+
image = Image.open(image_path).convert('RGB')
|
| 24 |
+
image = image.resize((size, size))
|
| 25 |
+
image = np.array(image) / 255.0
|
| 26 |
+
image = torch.from_numpy(image).permute(2, 0, 1).float().unsqueeze(0)
|
| 27 |
+
|
| 28 |
+
with torch.no_grad():
|
| 29 |
+
outputs = model(image)
|
| 30 |
+
|
| 31 |
+
probs = torch.sigmoid(outputs[0])
|
| 32 |
+
return [(i, score.item()) for i, score in enumerate(probs) if score > 0.5]
|
| 33 |
+
except Exception as e:
|
| 34 |
+
print(f"Error processing {image_path}: {str(e)}")
|
| 35 |
+
return []
|
| 36 |
+
|
| 37 |
+
def main():
|
| 38 |
+
parser = argparse.ArgumentParser()
|
| 39 |
+
parser.add_argument('--dir', required=True, help='画像が含まれるディレクトリのパス')
|
| 40 |
+
parser.add_argument('--after', help='この日付以降に更新されたファイルのみを処理 (YYYY-MM-DD形式)')
|
| 41 |
+
args = parser.parse_args()
|
| 42 |
+
|
| 43 |
+
print("Loading model...")
|
| 44 |
+
model = timm.create_model('hf-hub:SmilingWolf/wd-eva02-large-tagger-v3', pretrained=True)
|
| 45 |
+
model.eval()
|
| 46 |
+
|
| 47 |
+
print("Loading tag mapping...")
|
| 48 |
+
with open('selected_tags.csv', 'r', encoding='utf-8') as f:
|
| 49 |
+
reader = csv.reader(f)
|
| 50 |
+
next(reader) # ヘッダーをスキップ
|
| 51 |
+
tag_mapping = {i: row[0] for i, row in enumerate(reader)}
|
| 52 |
+
|
| 53 |
+
image_files = get_image_files(args.dir)
|
| 54 |
+
|
| 55 |
+
if args.after:
|
| 56 |
+
filter_date = datetime.strptime(args.after, '%Y-%m-%d')
|
| 57 |
+
image_files = [f for f in image_files if datetime.fromtimestamp(os.path.getmtime(f)) > filter_date]
|
| 58 |
+
|
| 59 |
+
output_file = "tags-wd-tagger.txt"
|
| 60 |
+
|
| 61 |
+
print(f"Processing {len(image_files)} images...")
|
| 62 |
+
|
| 63 |
+
with open(output_file, 'w', encoding='utf-8') as f:
|
| 64 |
+
for i, image_path in enumerate(image_files, 1):
|
| 65 |
+
start_time = time.time()
|
| 66 |
+
relative_path = os.path.relpath(image_path, args.dir)
|
| 67 |
+
|
| 68 |
+
tag_indices = process_image(image_path, model)
|
| 69 |
+
if tag_indices:
|
| 70 |
+
tags = [tag_mapping[idx] for idx, _ in tag_indices]
|
| 71 |
+
f.write(f"{relative_path}: {', '.join(tags)}\n")
|
| 72 |
+
|
| 73 |
+
elapsed = time.time() - start_time
|
| 74 |
+
print(f"Processed {i}/{len(image_files)} - {relative_path} ({elapsed:.2f}s)")
|
| 75 |
+
|
| 76 |
+
print(f"\nTagging complete. Results saved to {output_file}")
|
| 77 |
+
|
| 78 |
+
if __name__ == "__main__":
|
| 79 |
+
main()
|