无法从YOLOv4 Python对象检测中获取打印结果,PHP返回空白
P粉275883973
P粉275883973 2023-08-28 12:41:17
[PHP讨论组]

我正在使用这个git包在Python中使用YOLOv4运行目标检测

https://github.com/erentknn/yolov4-object-detection

脚本运行得很好,我可以在终端中打印出找到的目标,并且有信心,但是当我从PHP中执行它时,返回的结果是空的。我猜可能是因为PHP脚本在等待Python完成并且没有实时返回结果。我尝试创建一个字典来存储结果并在最后返回,但仍然返回为空。我以前可以很容易地在YOLOv3中做到这一点,不确定v4有什么变化。

编辑:经过更多的测试,我甚至无法将结果写入文件,这很奇怪。如果从终端运行,我可以。

编辑:如果我var_dump($output),它返回NULL。打开调试后,没有额外的信息返回。

我正在运行脚本 - yolo_video.py

# example usage: python3 yolo_video.py -i video.mp4 -o video_out.avi
import argparse
import glob
import time
import logging
from pathlib import Path
import cv2
import numpy as np

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s-%(name)s-%(message)s")

stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", type=str, default="",
                    help="video.mp4")
parser.add_argument("-o", "--output", type=str, default="",
                    help="path to (optional) output video file")
parser.add_argument("-d", "--display", type=int, default=1,
                    help="display output or not (1/0)")
parser.add_argument("-ht", "--height", type=int, default=1200,
                    help="height of output")
parser.add_argument("-wt", "--width", type=int, default=700,
                    help="width of output")
parser.add_argument("-c", "--confidence", type=float, default=0.8,
                    help="confidence threshold")
parser.add_argument("-t", "--threshold", type=float, default=0.6,
                    help="non-maximum supression threshold")

args = parser.parse_args()
logger.info("Parsed Arguments")

CONFIDENCE_THRESHOLD = args.confidence
NMS_THRESHOLD = args.threshold
if not Path(args.input).exists():
    raise FileNotFoundError("Path to video file is not exist.")

vc = cv2.VideoCapture(args.input)
weights = glob.glob("yolo/*.weights")[0]
labels = glob.glob("yolo/*.txt")[0]
cfg = glob.glob("yolo/*.cfg")[0]

logger.info("Using {} weights ,{} configs and {} labels.".format(weights, cfg, labels))

class_names = list()
with open(labels, "r") as f:
    class_names = [cname.strip() for cname in f.readlines()]

COLORS = np.random.randint(0, 255, size=(len(class_names), 3), dtype="uint8")

net = cv2.dnn.readNetFromDarknet(cfg, weights)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

layer = net.getLayerNames()
layer = [layer[i[0] - 1] for i in net.getUnconnectedOutLayers()]
writer = None


def detect(frm, net, ln):
    (H, W) = frm.shape[:2]
    blob = cv2.dnn.blobFromImage(frm, 1 / 255.0, (416, 416), swapRB=True, crop=False)
    net.setInput(blob)
    start_time = time.time()
    layerOutputs = net.forward(ln)
    end_time = time.time()

    boxes = []
    classIds = []
    confidences = []
    for output in layerOutputs:
        for detection in output:
            scores = detection[5:]
            classID = np.argmax(scores)
            confidence = scores[classID]

            if confidence > CONFIDENCE_THRESHOLD:
                box = detection[0:4] * np.array([W, H, W, H])
                (centerX, centerY, width, height) = box.astype("int")
                x = int(centerX - (width / 2))
                y = int(centerY - (height / 2))

                boxes.append([x, y, int(width), int(height)])
                classIds.append(classID)
                confidences.append(float(confidence))
                
    idxs = cv2.dnn.NMSBoxes(boxes, confidences, CONFIDENCE_THRESHOLD, NMS_THRESHOLD)

    if len(idxs) > 0:
        for i in idxs.flatten():
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])

            color = [int(c) for c in COLORS[classIds[i]]]
            cv2.rectangle(frm, (x, y), (x + w, y + h), color, 2)
            text = "{}: {:.4f}".format(class_names[classIds[i]], confidences[i])
            
            # 这里我打印结果(在终端中工作)
            print("found")
            print(confidences[i])
            print(class_names[classIds[i]])

            cv2.putText(
                frm, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2
            )
            
            fps_label = "FPS: %.2f" % (1 / (end_time - start_time))
            cv2.putText(
                frm, fps_label, (0, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2
            )


while cv2.waitKey(1) < 1:
    (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');
$output = shell_exec($command);
echo $output;

如何将Python脚本的结果在PHP中输出?我没有得到任何错误,脚本已经完成。

P粉275883973
P粉275883973

全部回复(1)
P粉360266095

cv2.waitKey在一般情况下不起作用,具体取决于您的机器是PHP还是jupyter notebook。

我在我的机器上尝试了这个,并解决了问题:

while(vc.isOpened()):

if frame is None:
        break

或者

if not grabbed:
        break

当视频播放完毕时,脚本将停止。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号