YOLOv4 Python オブジェクト検出から印刷結果を取得できず、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;"># 使用例: python3 yolo_video.py -i video.mp4 -o video_out.avi
引数解析をインポートする
グロブをインポートする
インポート時間
インポートログ
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="",
ヘルプ="ビデオ.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,default=1200,
help="出力の高さ")
parser.add_argument("-wt", "--width", type=int,default=700,
help="出力の幅")
parser.add_argument("-c", "--confidence", type=float,default=0.8,
help="信頼しきい値")
parser.add_argument("-t", "--threshold", type=float,default=0.6,
help="非最大抑制しきい値")
args = parser.parse_args()
logger.info("解析された引数")
CONFIDENCE_THRESHOLD = args.confidence
NMS_THRESHOLD = args.threshold
そうでない場合 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(weights, cfg, label))
クラス名 = リスト()
open(labels, "r") を f として使用:
class_names = [f.readlines() の cname の cname.strip()]
COLORS = 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 = [layer[i[0] - 1] for i in net.getUnconnectedOutLayers()]
ライター = なし
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(ブロブ)
start_time = time.time()
LayerOutputs = net.forward(ln)
end_time = time.time()
ボックス = []
クラスID = []
信頼度 = []
LayerOutputs での出力の場合:
出力での検出用:
スコア = 検出[5:]
クラスID = np.argmax(スコア)
信頼度 = スコア[クラスID]
自信がある場合 > CONFIDENCE_THRESHOLD:
ボックス = 検出[0:4] * np.array([W, H, W, H])
(中心X、中心Y、幅、高さ) = box.astype("int")
x = int(中心X - (幅 / 2))
y = int(中心Y - (高さ / 2))
box.append([x, y, int(幅), int(高さ)])
classIds.append(クラスID)
confidents.append(float(confidence))
idxs = cv2.dnn.NMSBoxes(ボックス、信頼度、CONFIDENCE_THRESHOLD、NMS_THRESHOLD)
if len(idxs) > 0:
idxs. flatten() の場合:
(x, y) = (ボックス[i][0], ボックス[i][1])
(w, h) = (ボックス[i][2], ボックス[i][3])
color = [int(c) for c in COLORS[classIds[i]]]
cv2.rectangle(frm, (x, y), (x w, y h), color, 2)
テキスト = "{}: {:.4f}".format(class_names[classIds[i]],confidences[i])
# ここで結果を出力します(ターミナルで作業)
print("見つかった")
print(信頼度[i])
print(クラス名[クラスIds[i]])
cv2.putText(
frm、テキスト、(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
)
一方 cv2.waitKey(1) < 1:
(取得、フレーム) = vc.read()
掴まれていない場合:
壊す
フレーム = cv2.resize(フレーム, (args.height, args.width))
検出(フレーム、ネット、レイヤー)
ライターが 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 = シェル_exec($command);
echo $output;</pre>
<p>Python スクリプトの結果を PHP で出力するにはどうすればよいですか?エラーは発生せず、スクリプトは完了します。 </p>