Тест-режим: отправлять на /check/ авто-кроп лица (как в превью/публикации), а не оригинал
- make_face_crop_bytes(): тот же квадратный кроп по центру лица, что превью и публикуемый кадр (полное разрешение, JPEG q90) - handlers: кнопка 1 шлёт на проверку кроп, не оригинал - правило «голова >= 30%» теперь меряется по публикуемому результату
This commit is contained in:
@@ -14,7 +14,7 @@ from trueconf.types import FSInputFile
|
|||||||
import config.config as config
|
import config.config as config
|
||||||
from utils import states
|
from utils import states
|
||||||
from utils.menu import MENU_TEXT
|
from utils.menu import MENU_TEXT
|
||||||
from photo_bot.photo_processor import prepare_ad_photo, get_crop_coordinates, check_photo_api
|
from photo_bot.photo_processor import prepare_ad_photo, get_crop_coordinates, check_photo_api, make_face_crop_bytes
|
||||||
from utils.texts import (
|
from utils.texts import (
|
||||||
UNKNOWN_MAIN_CMD_TEXT,
|
UNKNOWN_MAIN_CMD_TEXT,
|
||||||
EMOJI_DIGITS,
|
EMOJI_DIGITS,
|
||||||
@@ -339,9 +339,16 @@ async def photo_module_handler(msg: Message):
|
|||||||
try:
|
try:
|
||||||
with open(original_path, 'rb') as f:
|
with open(original_path, 'rb') as f:
|
||||||
raw_photo = f.read()
|
raw_photo = f.read()
|
||||||
|
# На проверку уходит АВТО-КРОП ЛИЦА (тот же, что в превью
|
||||||
|
# и что публикуется на сайте) — правила «голова ≥ 30%» и
|
||||||
|
# прочее имеют смысл для публикуемого результата, а не
|
||||||
|
# для произвольно снятого оригинала.
|
||||||
|
crop_bytes = await asyncio.to_thread(
|
||||||
|
make_face_crop_bytes, raw_photo, photo_data.get('coords')
|
||||||
|
)
|
||||||
# Dry-run: полный пайплайн проверки на САЙТЕ (CV + гримасы + ИИ),
|
# Dry-run: полный пайплайн проверки на САЙТЕ (CV + гримасы + ИИ),
|
||||||
# фото в БД/AD/Orion не попадает
|
# фото в БД/AD/Orion не попадает
|
||||||
check_res = await asyncio.to_thread(check_photo_api, raw_photo)
|
check_res = await asyncio.to_thread(check_photo_api, crop_bytes)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"🔥 [TEST MODE] Ошибка проверки фото: {e}")
|
logger.error(f"🔥 [TEST MODE] Ошибка проверки фото: {e}")
|
||||||
check_res = {"status": "error", "reason": f"Ошибка бота: {e}"}
|
check_res = {"status": "error", "reason": f"Ошибка бота: {e}"}
|
||||||
|
|||||||
@@ -189,13 +189,47 @@ def prepare_ad_photo(input_path: str, user_id: str, output_path: str = None, tar
|
|||||||
return {"success": False, "error": str(e)}
|
return {"success": False, "error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
|
def make_face_crop_bytes(image_bytes: bytes, coords: tuple) -> bytes:
|
||||||
|
"""
|
||||||
|
Вырезает квадратный кадр по центру лица (тот же регион, что превью
|
||||||
|
бота и публикуемый на сайте кроп) и возвращает JPEG-байты.
|
||||||
|
|
||||||
|
На проверку уходит именно этот кроп: правило «голова ≥ 30%» и все
|
||||||
|
дальнейшие проверки имеют смысл для публикуемого результата, а не
|
||||||
|
для произвольно снятого оригинала.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JPEG-байты квадрата (полное разрешение, без ресайза).
|
||||||
|
"""
|
||||||
|
from PIL import Image
|
||||||
|
import io
|
||||||
|
|
||||||
|
img = Image.open(io.BytesIO(image_bytes))
|
||||||
|
if img.mode != 'RGB':
|
||||||
|
img = img.convert('RGB')
|
||||||
|
|
||||||
|
x1, y1, x2, y2 = coords
|
||||||
|
cropped = img.crop((x1, y1, x2, y2))
|
||||||
|
|
||||||
|
# Квадрат из центра (как превью)
|
||||||
|
side = min(cropped.size[0], cropped.size[1])
|
||||||
|
left = (cropped.size[0] - side) // 2
|
||||||
|
top = (cropped.size[1] - side) // 2
|
||||||
|
cropped = cropped.crop((left, top, left + side, top + side))
|
||||||
|
|
||||||
|
buf = io.BytesIO()
|
||||||
|
cropped.save(buf, format="JPEG", quality=90)
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
def check_photo_api(image_bytes: bytes, timeout: float = 300.0) -> dict:
|
def check_photo_api(image_bytes: bytes, timeout: float = 300.0) -> dict:
|
||||||
"""
|
"""
|
||||||
Dry-run проверка фото через API сайта (POST /api/photo-bot/check/).
|
Dry-run проверка фото через API сайта (POST /api/photo-bot/check/).
|
||||||
|
|
||||||
Фото проходит полный пайплайн проверки на сайте (MediaPipe CV +
|
image_bytes — АВТО-КРОП ЛИЦА от бота (make_face_crop_bytes), тот же
|
||||||
ARKit-формы + VLM ИИ), НО ни в БД, ни в AD, ни в Orion не попадает —
|
кадр, что и превью/публикация. Фото проходит полный пайплайн проверки
|
||||||
ответ возвращается боту для тест-под-режима.
|
на сайте (MediaPipe CV + ARKit-формы + VLM ИИ), НО ни в БД, ни в AD,
|
||||||
|
ни в Orion не попадает — ответ возвращается боту для тест-под-режима.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
{"status": "ok", "verdict", "ai_reason", "cv_approved", "cv_reason",
|
{"status": "ok", "verdict", "ai_reason", "cv_approved", "cv_reason",
|
||||||
|
|||||||
Reference in New Issue
Block a user