无法从YOLOv4 Python对象检测中获取打印结果,PHP返回空白
P粉275883973
2023-08-28 12:41:17
[PHP讨论组]
<p>我正在使用这个git包在Python中使用YOLOv4运行目标检测</p>
<pre class="brush:php;toolbar:false;">https://github.com/erentknn/yolov4-object-detection</pre>
<p>脚本运行得很好,我可以在终端中打印出找到的目标,并且有信心,但是当我从PHP中执行它时,返回的结果是空的。我猜可能是因为PHP脚本在等待Python完成并且没有实时返回结果。我尝试创建一个字典来存储结果并在最后返回,但仍然返回为空。我以前可以很容易地在YOLOv3中做到这一点,不确定v4有什么变化。</p>
<p>编辑:经过更多的测试,我甚至无法将结果写入文件,这很奇怪。如果从终端运行,我可以。</p>
<p>编辑:如果我var_dump($output),它返回NULL。打开调试后,没有额外的信息返回。</p>
<p>我正在运行脚本 - yolo_video.py</p>
<pre class="brush:php;toolbar:false;"># 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)</pre>
<p>然后在我的PHP脚本中</p>
<pre class="brush:php;toolbar:false;">$command = escapeshellcmd('python3 yolo_video.py -i video.mp4 -o video_out.avi');
$output = shell_exec($command);
echo $output;</pre>
<p>如何将Python脚本的结果在PHP中输出?我没有得到任何错误,脚本已经完成。</p>
cv2.waitKey
在一般情况下不起作用,具体取决于您的机器是PHP还是jupyter notebook。我在我的机器上尝试了这个,并解决了问题:
或者
当视频播放完毕时,脚本将停止。