首頁  >  問答  >  主體

無法從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>
# 用法範例: 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>
P粉275883973P粉275883973439 天前682

全部回覆(1)我來回復

  • P粉360266095

    P粉3602660952023-08-29 09:53:20

    cv2.waitKey在一般情況下不起作用,具體取決於您的機器是PHP還是jupyter notebook。

    我在我的機器上嘗試了這個,並解決了問題:

    while(vc.isOpened()):
    
    if frame is None:
            break

    if not grabbed:
            break

    當影片播放完畢時,腳本將停止。

    回覆
    0
  • 取消回覆