170 слов | 1 минута
Интеграция YOLOv8 с PHP (1C-Битрикс)
Напрямую запускать нейросети внутри PHP (через exec) неэффективно, так как загрузка модели в память занимает время (1–3 секунды на каждый запрос).
Оптимальное решение: Архитектура микросервиса.
- Python-скрипт висит в памяти, один раз загружает модель и ждет запросы.
- PHP отправляет картинку на локальный порт (например, 5000) и мгновенно получает JSON с координатами карт.
Настройка Python сервиса
Этот сервис будет работать на том же сервере, где установлен 1С-Битрикс.
Установка зависимостей
Выполните в консоли сервера:
pip install fastapi uvicorn ultralytics python-multipart
Создание сервиса
Создайте файл poker_api.py:
from fastapi import FastAPI, UploadFile, File
from ultralytics import YOLO
from PIL import Image
import io
app = FastAPI()
# Загружаем модель ОДИН раз при старте
# Укажите полный путь к файлу, если он не в той же папке
model = YOLO("yolov8m.pt")
@app.post("/predict")
async def predict(file: UploadFile = File(...)):
# Читаем картинку из памяти без сохранения на диск
image_data = await file.read()
image = Image.open(io.BytesIO(image_data))
# Распознаем
results = model(image)
# Формируем JSON ответ
cards = []
for r in results:
for box in r.boxes:
# Получаем ID класса, имя и точность
cls_id = int(box.cls[0])
class_name = model.names[cls_id]
conf = float(box.conf[0])
cards.append({
"card": class_name,
"confidence": round(conf, 2),
"box": box.xywh.tolist()[0] # координаты [x, y, w, h]
})
return {"result": cards}
Запуск сервиса
Запустите сервер (для тестов):
uvicorn poker_api:app --host 127.0.0.1 --port 5000
(Для продакшна рекомендуется использовать systemd или supervisor, чтобы скрипт работал в фоне).
Интеграция в PHP (Битрикс)
Используем стандартный класс Bitrix\Main\Web\HttpClient, чтобы не зависеть от сторонних библиотек.
Добавьте этот код в ваш класс, компонент или init.php:
use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Json;
function recognizeCards($filePath) {
$httpClient = new HttpClient();
// Формируем multipart-запрос вручную (для отправки файла)
$boundary = '--------------------------' . microtime(true);
$httpClient->setHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);
// Проверка существования файла
if (!file_exists($filePath)) {
return false;
}
$fileContent = file_get_contents($filePath);
$filename = basename($filePath);
// Тело запроса
$body = "--" . $boundary . "\r\n";
$body .= "Content-Disposition: form-data; name=\"file\"; filename=\"" . $filename . "\"\r\n";
$body .= "Content-Type: image/jpeg\r\n\r\n";
$body .= $fileContent . "\r\n";
$body .= "--" . $boundary . "--\r\n";
// Отправляем запрос локальному Python-сервису
$response = $httpClient->post('http://127.0.0.1:5000/predict', $body);
// Обработка ответа
if ($httpClient->getStatus() == 200) {
try {
$data = Json::decode($response);
return $data['result']; // Возвращаем массив карт
} catch (\Exception $e) {
// Логирование ошибки JSON
return false;
}
}
return false;
}
Пример использования
$imagePath = $_SERVER["DOCUMENT_ROOT"] . "/upload/poker_screen.jpg";
$cards = recognizeCards($imagePath);
if ($cards) {
foreach ($cards as $card) {
echo "Карта: <b>" . $card['card'] . "</b> ";
echo "(Вероятность: " . ($card['confidence'] * 100) . "%)<br>";
}
} else {
echo "Не удалось распознать карты или ошибка сервиса.";
}
Преимущества подхода
- Скорость: Модель YOLOv8m (Medium) весит ~50 МБ. При использовании микросервиса она загружается в оперативную память один раз. Обработка запроса занимает доли секунды.
- Надежность: Ошибка в Python-скрипте не уронит PHP-процесс Битрикса.
- Масштабируемость: При высокой нагрузке Python-сервис можно вынести на отдельный сервер с GPU.