<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>
# 用法示例: python3 yolo_video.py -i video.mp4 -o video_out.avi
导入argparse
导入全局
导入时间
导入日志记录
从 pathlib 导入路径
导入CV2
将 numpy 导入为 np
记录器=logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter =logging.Formatter("%(asctime)s-%(name)s-%(message)s")
Stream_handler =logging.StreamHandler()
Stream_handler.setFormatter(格式化程序)
logger.addHandler(stream_handler)
解析器 = argparse.ArgumentParser()
parser.add_argument("-i", "--input", type=str, default="",
帮助=“video.mp4”)
parser.add_argument("-o", "--output", type=str, default="",
help=“(可选)输出视频文件的路径”)
parser.add_argument("-d", "--display", type=int, default=1,
help="是否显示输出(1/0)")
parser.add_argument("-ht", "--height", type=int, 默认=1200,
help=“输出高度”)
parser.add_argument("-wt", "--width", type=int, 默认=700,
help="输出宽度")
parser.add_argument("-c", "--confidence", type=float, 默认=0.8,
help=“置信阈值”)
parser.add_argument("-t", "--threshold", type=float, 默认=0.6,
help=“非最大抑制阈值”)
args = parser.parse_args()
logger.info(“解析的参数”)
CONFIDENCE_THRESHOLD = args.confidence
NMS_THRESHOLD = args.阈值
如果不是 Path(args.input).exists():
raise FileNotFoundError(“视频文件的路径不存在。”)
vc = cv2.VideoCapture(args.input)
权重 = glob.glob(“yolo/*.weights”)[0]
标签 = glob.glob(“yolo/*.txt”)[0]
cfg = glob.glob(“yolo/*.cfg”)[0]
logger.info(“使用 {} 权重、{} 配置和 {}标签。”.format(权重、cfg、标签))
类名 = 列表()
将 open(labels, "r") 作为 f:
class_names = [cname.strip() for cname in f.readlines()]
颜色 = np.random.randint(0, 255, size=(len(class_names), 3), dtype=“uint8”)
net = cv2.dnn.readNetFromDarknet(cfg, 权重)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
层 = net.getLayerNames()
层 = [layer[i[0] - 1] for i in net.getUnconnectedOutLayers()]
作者=无
def 检测(frm、net、ln):
(H, W) = frm.shape[:2]
blob = cv2.dnn.blobFromImage(frm, 1 / 255.0, (416, 416), swapRB=True, 作物=False)
net.setInput(blob)
开始时间 = 时间.time()
层输出 = net.forward(ln)
结束时间 = time.time()
盒子=[]
类ID = []
信心 = []
对于layerOutputs中的输出:
用于输出中的检测:
分数 = 检测[5:]
classID = np.argmax(分数)
置信度 = 分数[classID]
如果置信度>置信度阈值:
box = 检测[0:4] * np.array([W, H, W, H])
(centerX, centerY, 宽度, 高度) = box.astype("int")
x = int(centerX - (宽度 / 2))
y = int(centerY - (高度 / 2))
box.append([x, y, int(宽度), int(高度)])
classIds.append(classID)
confidences.append(float(置信度))
idxs = cv2.dnn.NMSBoxes(框、置信度、CONFIDENCE_THRESHOLD、NMS_THRESHOLD)
如果 len(idxs) > 0:
对于 idxs.flatten() 中的 i:
(x, y) = (盒子[i][0], 盒子[i][1])
(w, h) = (盒子[i][2], 盒子[i][3])
颜色 = [int(c) for c in COLORS[classIds[i]]]
cv2.矩形(frm,(x,y),(x + w,y + h),颜色,2)
文本 =“{}: {:.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。我在我的机器上尝试了这个,并解决了问题:
或者
当视频播放完毕时,脚本将停止。