You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中获取YOLOv4 Python目标检测的输出结果?

问题描述

使用YOLOv4的Python目标检测脚本,终端运行时可正常打印检测到的物体及对应置信度,但通过PHP调用时返回空结果,var_dump($output)返回NULL。补充测试发现:Python脚本在PHP调用时无法写入文件,终端运行则正常;此前YOLOv3可轻松实现PHP调用,不清楚YOLOv4有何变化。

核心代码片段:

  • Python脚本yolo_video.py中通过print输出检测结果
  • PHP调用代码使用shell_exec执行Python命令
解决方案

1. 强制刷新Python输出缓冲区

Python的print默认在非交互模式下会缓冲输出,导致PHP无法实时捕获结果。修改print语句添加flush=True参数:

# 替换原输出代码
print("found", flush=True)
print(confidences[i], flush=True)
print(class_names[classIds[i]], flush=True)

或在脚本开头全局设置强制刷新:

import sys
sys.stdout = sys.stderr = open('/dev/stdout', 'w', buffering=1)

2. 捕获标准错误输出

shell_exec仅捕获标准输出(stdout),若Python脚本出错输出到标准错误(stderr),不会被PHP捕获。修改PHP代码将stderr重定向到stdout:

$command = escapeshellcmd('python3 yolo_video.py -i video.mp4 -o video_out.avi 2>&1');
$output = shell_exec($command);
var_dump($output);

此操作可暴露脚本执行时的权限、路径或依赖错误。

3. 修复权限与路径问题

  • 权限问题:PHP运行用户(通常为www-data)可能无脚本或视频文件的读写权限,执行以下命令开放权限:
    chown -R www-data:www-data /绝对路径/到/yolov4目录
    chmod -R 755 /绝对路径/到/yolov4目录
    
  • 相对路径问题:PHP调用时的工作目录与终端不同,将脚本中的相对路径改为绝对路径:
    base_path = "/绝对路径/到/yolov4目录"
    weights = glob.glob(f"{base_path}/yolo/*.weights")[0]
    labels = glob.glob(f"{base_path}/yolo/*.txt")[0]
    cfg = glob.glob(f"{base_path}/yolo/*.cfg")[0]
    

4. 禁用CV2图形界面

PHP运行环境无图形界面,cv2.waitKey(1)会导致脚本阻塞或出错。修改循环逻辑并添加-d 0参数禁用显示:

  • Python脚本替换循环:
    while True:
        (grabbed, frame) = vc.read()
        if not grabbed:
            break
        frame = cv2.resize(frame, (args.height, args.width))
        detect(frame, net, layer)
    
        if writer is not None:
            writer.write(frame)
    
  • PHP调用添加参数:
    $command = escapeshellcmd('python3 yolo_video.py -i video.mp4 -o video_out.avi -d 0 2>&1');
    

5. 使用proc_open替代shell_exec

proc_open可实时捕获stdout和stderr,比shell_exec更可靠:

$descriptorspec = [
    0 => ["pipe", "r"],  // 标准输入
    1 => ["pipe", "w"],  // 标准输出
    2 => ["pipe", "w"]   // 标准错误
];

$process = proc_open('python3 yolo_video.py -i video.mp4 -o video_out.avi -d 0', $descriptorspec, $pipes);

if (is_resource($process)) {
    $stdout = stream_get_contents($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    foreach ($pipes as $pipe) fclose($pipe);
    proc_close($process);
    
    echo "输出结果:<br>" . nl2br($stdout);
    echo "错误信息:<br>" . nl2br($stderr);
}

内容的提问来源于stack exchange,提问作者Ryan D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:30:52