Initial commit: Miku Discord Bot

This commit is contained in:
2025-12-07 17:15:09 +02:00
commit 8c74ad5260
206 changed files with 50125 additions and 0 deletions

20
face-detector/Dockerfile Normal file
View File

@@ -0,0 +1,20 @@
FROM ghcr.io/ayutaz/anime-face-detector:gpu-cuda12.1
# Install supervisor and FastAPI dependencies
RUN apt-get update && \
apt-get install -y supervisor && \
rm -rf /var/lib/apt/lists/* && \
pip install --no-cache-dir fastapi uvicorn python-multipart
# Copy supervisor config
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy API
COPY api /app/api
WORKDIR /app
# Expose ports
EXPOSE 7860 6078
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

132
face-detector/api/main.py Normal file
View File

@@ -0,0 +1,132 @@
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import JSONResponse
from anime_face_detector import create_detector
import numpy as np
import cv2
import os
import json
from datetime import datetime
from pathlib import Path
app = FastAPI(title="Anime Face Detector API")
# Create output directory
OUTPUT_DIR = Path("/app/api/outputs")
OUTPUT_DIR.mkdir(exist_ok=True)
# Load detector once at startup
detector = None
@app.on_event("startup")
async def startup_event():
global detector
detector = create_detector("yolov3", device="cuda:0")
@app.get("/")
async def root():
return {"message": "Anime Face Detector API", "status": "running"}
@app.get("/health")
async def health():
return {"status": "healthy", "detector_loaded": detector is not None}
@app.post("/detect")
async def detect_face(file: UploadFile = File(...)):
try:
if detector is None:
return JSONResponse(
status_code=503,
content={"error": "Detector not initialized yet"}
)
image_bytes = await file.read()
# Decode image
nparr = np.frombuffer(image_bytes, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
return JSONResponse(
status_code=400,
content={"error": "Invalid image file"}
)
# Run detector
preds = detector(img)
# Convert output to JSON-safe structure
result = []
for pred in preds:
# bbox contains [x1, y1, x2, y2, score]
bbox = pred['bbox']
bbox_coords = bbox[:4].tolist()
score = float(bbox[4])
# keypoints contains [[x, y, score], ...]
keypoints = pred.get('keypoints', [])
landmarks = [[float(pt[0]), float(pt[1]), float(pt[2])] for pt in keypoints]
result.append({
"bbox": bbox_coords,
"confidence": score,
"keypoints": landmarks
})
# Draw detection results on image (like Gradio demo)
annotated_img = img.copy()
for pred in preds:
box = pred['bbox']
box_coords, score = box[:4], box[4]
box_coords = np.round(box_coords).astype(int)
# Calculate line thickness based on image size
lt = max(2, int(3 * (box_coords[2:] - box_coords[:2]).max() / 256))
# Draw bounding box
cv2.rectangle(annotated_img,
tuple(box_coords[:2]),
tuple(box_coords[2:]),
(0, 255, 0), lt)
# Draw keypoints
pred_pts = pred['keypoints']
for *pt, kp_score in pred_pts:
# Color based on keypoint confidence
if kp_score < 0.3: # Low confidence
color = (0, 255, 255) # Yellow
else:
color = (0, 0, 255) # Red
pt = np.round(pt).astype(int)
cv2.circle(annotated_img, tuple(pt), lt, color, cv2.FILLED)
# Generate unique filename based on timestamp
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
original_filename = Path(file.filename).stem if file.filename else "image"
# Save annotated image
image_output_path = OUTPUT_DIR / f"{original_filename}_{timestamp}_annotated.jpg"
cv2.imwrite(str(image_output_path), annotated_img)
# Save JSON results
json_output_path = OUTPUT_DIR / f"{original_filename}_{timestamp}_results.json"
json_data = {
"filename": file.filename,
"timestamp": timestamp,
"detections": result,
"count": len(result)
}
with open(json_output_path, 'w') as f:
json.dump(json_data, f, indent=2)
return {
"detections": result,
"count": len(result),
"annotated_image": str(image_output_path),
"json_file": str(json_output_path)
}
except Exception as e:
return JSONResponse(
status_code=500,
content={"error": str(e)}
)

View File

@@ -0,0 +1,5 @@
# API Outputs
This directory contains detection results from the face detection API.
Files are automatically saved when processing images for profile picture cropping.

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@@ -0,0 +1,158 @@
{
"filename": "image.jpg",
"timestamp": "20251207_122113_777822",
"detections": [
{
"bbox": [
354.4007568359375,
179.347900390625,
583.9456787109375,
407.79052734375
],
"confidence": 0.9997539520263672,
"keypoints": [
[
355.96990966796875,
278.9985046386719,
0.8552265167236328
],
[
389.59466552734375,
346.24798583984375,
0.7313618659973145
],
[
470.2940368652344,
393.3226318359375,
0.8928672075271606
],
[
544.2684936523438,
346.24798583984375,
0.51087486743927
],
[
582.3765258789062,
276.7568359375,
0.8734480142593384
],
[
373.9031066894531,
229.6822052001953,
1.023979663848877
],
[
403.0445556640625,
227.4405517578125,
1.0816552639007568
],
[
434.4276428222656,
229.6822052001953,
0.9606916904449463
],
[
483.7439270019531,
229.6822052001953,
0.8983083963394165
],
[
517.3687133789062,
222.95724487304688,
0.8630613088607788
],
[
553.235107421875,
225.1988983154297,
0.9475551843643188
],
[
373.9031066894531,
276.7568359375,
0.9371979236602783
],
[
400.80291748046875,
263.30694580078125,
0.9300950765609741
],
[
432.1860046386719,
270.0318908691406,
0.9376640319824219
],
[
389.59466552734375,
294.6900329589844,
0.7016466856002808
],
[
407.5278625488281,
301.41497802734375,
0.8654309511184692
],
[
425.4610595703125,
299.17333984375,
0.9739865064620972
],
[
501.6771240234375,
272.2735290527344,
0.9432567358016968
],
[
535.3018798828125,
261.0653076171875,
0.8686380386352539
],
[
562.20166015625,
274.51519775390625,
0.8868838548660278
],
[
510.64373779296875,
299.17333984375,
0.9250255823135376
],
[
530.818603515625,
301.41497802734375,
0.7558021545410156
],
[
550.993408203125,
296.93170166015625,
0.7241212129592896
],
[
465.81072998046875,
319.3481750488281,
0.9815038442611694
],
[
459.0857849121094,
355.2145690917969,
0.9347469806671143
],
[
465.81072998046875,
355.2145690917969,
0.8932937383651733
],
[
472.53570556640625,
355.2145690917969,
0.9401137828826904
],
[
465.81072998046875,
355.2145690917969,
0.9636585712432861
]
]
}
],
"count": 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,158 @@
{
"filename": "image.jpg",
"timestamp": "20251207_123323_105009",
"detections": [
{
"bbox": [
1014.4192504882812,
424.75347900390625,
1413.239501953125,
803.3748779296875
],
"confidence": 0.9998574256896973,
"keypoints": [
[
1032.7244873046875,
596.5379028320312,
0.8433655500411987
],
[
1075.56640625,
701.6956176757812,
0.8955879211425781
],
[
1227.4609375,
775.6954956054688,
0.9430454969406128
],
[
1352.09228515625,
690.0114135742188,
0.545304536819458
],
[
1387.144775390625,
557.5906372070312,
0.7187260985374451
],
[
1040.513916015625,
491.3802490234375,
0.7835320234298706
],
[
1083.35595703125,
464.11712646484375,
0.8953272104263306
],
[
1137.882080078125,
464.11712646484375,
0.9976778030395508
],
[
1246.9345703125,
456.3276672363281,
0.9387356638908386
],
[
1297.5660400390625,
448.5382080078125,
0.9407274723052979
],
[
1344.302734375,
460.222412109375,
0.8987929821014404
],
[
1063.88232421875,
588.7484741210938,
0.8896710276603699
],
[
1098.934814453125,
549.8012084960938,
0.9300478100776672
],
[
1153.4610595703125,
565.3800659179688,
0.8939650654792786
],
[
1087.2506103515625,
619.9063110351562,
0.8864291310310364
],
[
1122.30322265625,
627.6957397460938,
0.9993363618850708
],
[
1153.4610595703125,
616.0115966796875,
0.9245419502258301
],
[
1250.8292236328125,
549.8012084960938,
0.8676242232322693
],
[
1301.460693359375,
522.5380859375,
0.9180043935775757
],
[
1348.197509765625,
549.8012084960938,
0.8424603939056396
],
[
1270.302978515625,
596.5379028320312,
0.8135454654693604
],
[
1305.35546875,
608.2221069335938,
0.9596346616744995
],
[
1336.5133056640625,
592.6431884765625,
0.820756733417511
],
[
1196.3031005859375,
639.3799438476562,
0.8221449255943298
],
[
1169.0399169921875,
693.9061279296875,
0.9530820846557617
],
[
1219.67138671875,
678.3272094726562,
0.9687690138816833
],
[
1266.408203125,
682.2219848632812,
0.9659124612808228
],
[
1223.566162109375,
717.2745361328125,
0.8905119895935059
]
]
}
],
"count": 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@@ -0,0 +1,158 @@
{
"filename": "image.jpg",
"timestamp": "20251207_123514_060692",
"detections": [
{
"bbox": [
354.4007568359375,
179.347900390625,
583.9456787109375,
407.79052734375
],
"confidence": 0.9997539520263672,
"keypoints": [
[
355.96990966796875,
278.9985046386719,
0.8552265167236328
],
[
389.59466552734375,
346.24798583984375,
0.7313618659973145
],
[
470.2940368652344,
393.3226318359375,
0.8928672075271606
],
[
544.2684936523438,
346.24798583984375,
0.51087486743927
],
[
582.3765258789062,
276.7568359375,
0.8734480142593384
],
[
373.9031066894531,
229.6822052001953,
1.023979663848877
],
[
403.0445556640625,
227.4405517578125,
1.0816552639007568
],
[
434.4276428222656,
229.6822052001953,
0.9606916904449463
],
[
483.7439270019531,
229.6822052001953,
0.8983083963394165
],
[
517.3687133789062,
222.95724487304688,
0.8630613088607788
],
[
553.235107421875,
225.1988983154297,
0.9475551843643188
],
[
373.9031066894531,
276.7568359375,
0.9371979236602783
],
[
400.80291748046875,
263.30694580078125,
0.9300950765609741
],
[
432.1860046386719,
270.0318908691406,
0.9376640319824219
],
[
389.59466552734375,
294.6900329589844,
0.7016466856002808
],
[
407.5278625488281,
301.41497802734375,
0.8654309511184692
],
[
425.4610595703125,
299.17333984375,
0.9739865064620972
],
[
501.6771240234375,
272.2735290527344,
0.9432567358016968
],
[
535.3018798828125,
261.0653076171875,
0.8686380386352539
],
[
562.20166015625,
274.51519775390625,
0.8868838548660278
],
[
510.64373779296875,
299.17333984375,
0.9250255823135376
],
[
530.818603515625,
301.41497802734375,
0.7558021545410156
],
[
550.993408203125,
296.93170166015625,
0.7241212129592896
],
[
465.81072998046875,
319.3481750488281,
0.9815038442611694
],
[
459.0857849121094,
355.2145690917969,
0.9347469806671143
],
[
465.81072998046875,
355.2145690917969,
0.8932937383651733
],
[
472.53570556640625,
355.2145690917969,
0.9401137828826904
],
[
465.81072998046875,
355.2145690917969,
0.9636585712432861
]
]
}
],
"count": 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@@ -0,0 +1,158 @@
{
"filename": "image.jpg",
"timestamp": "20251207_123836_228498",
"detections": [
{
"bbox": [
354.4007568359375,
179.347900390625,
583.9456787109375,
407.79052734375
],
"confidence": 0.9997539520263672,
"keypoints": [
[
355.96990966796875,
278.9985046386719,
0.8552265167236328
],
[
389.59466552734375,
346.24798583984375,
0.7313618659973145
],
[
470.2940368652344,
393.3226318359375,
0.8928672075271606
],
[
544.2684936523438,
346.24798583984375,
0.51087486743927
],
[
582.3765258789062,
276.7568359375,
0.8734480142593384
],
[
373.9031066894531,
229.6822052001953,
1.023979663848877
],
[
403.0445556640625,
227.4405517578125,
1.0816552639007568
],
[
434.4276428222656,
229.6822052001953,
0.9606916904449463
],
[
483.7439270019531,
229.6822052001953,
0.8983083963394165
],
[
517.3687133789062,
222.95724487304688,
0.8630613088607788
],
[
553.235107421875,
225.1988983154297,
0.9475551843643188
],
[
373.9031066894531,
276.7568359375,
0.9371979236602783
],
[
400.80291748046875,
263.30694580078125,
0.9300950765609741
],
[
432.1860046386719,
270.0318908691406,
0.9376640319824219
],
[
389.59466552734375,
294.6900329589844,
0.7016466856002808
],
[
407.5278625488281,
301.41497802734375,
0.8654309511184692
],
[
425.4610595703125,
299.17333984375,
0.9739865064620972
],
[
501.6771240234375,
272.2735290527344,
0.9432567358016968
],
[
535.3018798828125,
261.0653076171875,
0.8686380386352539
],
[
562.20166015625,
274.51519775390625,
0.8868838548660278
],
[
510.64373779296875,
299.17333984375,
0.9250255823135376
],
[
530.818603515625,
301.41497802734375,
0.7558021545410156
],
[
550.993408203125,
296.93170166015625,
0.7241212129592896
],
[
465.81072998046875,
319.3481750488281,
0.9815038442611694
],
[
459.0857849121094,
355.2145690917969,
0.9347469806671143
],
[
465.81072998046875,
355.2145690917969,
0.8932937383651733
],
[
472.53570556640625,
355.2145690917969,
0.9401137828826904
],
[
465.81072998046875,
355.2145690917969,
0.9636585712432861
]
]
}
],
"count": 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@@ -0,0 +1,158 @@
{
"filename": "image.jpg",
"timestamp": "20251207_133902_439938",
"detections": [
{
"bbox": [
354.4007568359375,
179.347900390625,
583.9456787109375,
407.79052734375
],
"confidence": 0.9997539520263672,
"keypoints": [
[
355.96990966796875,
278.9985046386719,
0.8552265167236328
],
[
389.59466552734375,
346.24798583984375,
0.7313618659973145
],
[
470.2940368652344,
393.3226318359375,
0.8928672075271606
],
[
544.2684936523438,
346.24798583984375,
0.51087486743927
],
[
582.3765258789062,
276.7568359375,
0.8734480142593384
],
[
373.9031066894531,
229.6822052001953,
1.023979663848877
],
[
403.0445556640625,
227.4405517578125,
1.0816552639007568
],
[
434.4276428222656,
229.6822052001953,
0.9606916904449463
],
[
483.7439270019531,
229.6822052001953,
0.8983083963394165
],
[
517.3687133789062,
222.95724487304688,
0.8630613088607788
],
[
553.235107421875,
225.1988983154297,
0.9475551843643188
],
[
373.9031066894531,
276.7568359375,
0.9371979236602783
],
[
400.80291748046875,
263.30694580078125,
0.9300950765609741
],
[
432.1860046386719,
270.0318908691406,
0.9376640319824219
],
[
389.59466552734375,
294.6900329589844,
0.7016466856002808
],
[
407.5278625488281,
301.41497802734375,
0.8654309511184692
],
[
425.4610595703125,
299.17333984375,
0.9739865064620972
],
[
501.6771240234375,
272.2735290527344,
0.9432567358016968
],
[
535.3018798828125,
261.0653076171875,
0.8686380386352539
],
[
562.20166015625,
274.51519775390625,
0.8868838548660278
],
[
510.64373779296875,
299.17333984375,
0.9250255823135376
],
[
530.818603515625,
301.41497802734375,
0.7558021545410156
],
[
550.993408203125,
296.93170166015625,
0.7241212129592896
],
[
465.81072998046875,
319.3481750488281,
0.9815038442611694
],
[
459.0857849121094,
355.2145690917969,
0.9347469806671143
],
[
465.81072998046875,
355.2145690917969,
0.8932937383651733
],
[
472.53570556640625,
355.2145690917969,
0.9401137828826904
],
[
465.81072998046875,
355.2145690917969,
0.9636585712432861
]
]
}
],
"count": 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

View File

@@ -0,0 +1,158 @@
{
"filename": "image.jpg",
"timestamp": "20251207_134638_852682",
"detections": [
{
"bbox": [
354.4007568359375,
179.347900390625,
583.9456787109375,
407.79052734375
],
"confidence": 0.9997539520263672,
"keypoints": [
[
355.96990966796875,
278.9985046386719,
0.8552265167236328
],
[
389.59466552734375,
346.24798583984375,
0.7313618659973145
],
[
470.2940368652344,
393.3226318359375,
0.8928672075271606
],
[
544.2684936523438,
346.24798583984375,
0.51087486743927
],
[
582.3765258789062,
276.7568359375,
0.8734480142593384
],
[
373.9031066894531,
229.6822052001953,
1.023979663848877
],
[
403.0445556640625,
227.4405517578125,
1.0816552639007568
],
[
434.4276428222656,
229.6822052001953,
0.9606916904449463
],
[
483.7439270019531,
229.6822052001953,
0.8983083963394165
],
[
517.3687133789062,
222.95724487304688,
0.8630613088607788
],
[
553.235107421875,
225.1988983154297,
0.9475551843643188
],
[
373.9031066894531,
276.7568359375,
0.9371979236602783
],
[
400.80291748046875,
263.30694580078125,
0.9300950765609741
],
[
432.1860046386719,
270.0318908691406,
0.9376640319824219
],
[
389.59466552734375,
294.6900329589844,
0.7016466856002808
],
[
407.5278625488281,
301.41497802734375,
0.8654309511184692
],
[
425.4610595703125,
299.17333984375,
0.9739865064620972
],
[
501.6771240234375,
272.2735290527344,
0.9432567358016968
],
[
535.3018798828125,
261.0653076171875,
0.8686380386352539
],
[
562.20166015625,
274.51519775390625,
0.8868838548660278
],
[
510.64373779296875,
299.17333984375,
0.9250255823135376
],
[
530.818603515625,
301.41497802734375,
0.7558021545410156
],
[
550.993408203125,
296.93170166015625,
0.7241212129592896
],
[
465.81072998046875,
319.3481750488281,
0.9815038442611694
],
[
459.0857849121094,
355.2145690917969,
0.9347469806671143
],
[
465.81072998046875,
355.2145690917969,
0.8932937383651733
],
[
472.53570556640625,
355.2145690917969,
0.9401137828826904
],
[
465.81072998046875,
355.2145690917969,
0.9636585712432861
]
]
}
],
"count": 1
}

View File

@@ -0,0 +1,23 @@
[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisor
[program:gradio]
command=python demo_gradio.py
directory=/app
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/gradio.err.log
stdout_logfile=/var/log/supervisor/gradio.out.log
environment=PYTHONUNBUFFERED="1"
[program:api]
command=uvicorn api.main:app --host 0.0.0.0 --port 6078
directory=/app
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/api.err.log
stdout_logfile=/var/log/supervisor/api.out.log
environment=PYTHONUNBUFFERED="1"