|
@@ -319,9 +319,23 @@ def yolov12_predict(params: PredictParams):
|
|
|
if field not in ['model'] and value is not None:
|
|
if field not in ['model'] and value is not None:
|
|
|
predict_kwargs[field] = value
|
|
predict_kwargs[field] = value
|
|
|
|
|
|
|
|
- # 确保保存结果
|
|
|
|
|
|
|
+ # 确保保存结果,并强制使用MP4格式
|
|
|
predict_kwargs['save'] = True
|
|
predict_kwargs['save'] = True
|
|
|
|
|
|
|
|
|
|
+ # 如果输入是视频,强制设置输出格式为MP4
|
|
|
|
|
+ source = params.source
|
|
|
|
|
+ if source:
|
|
|
|
|
+ import os
|
|
|
|
|
+ source_ext = os.path.splitext(source)[1].lower()
|
|
|
|
|
+ video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.webm', '.flv', '.wmv']
|
|
|
|
|
+
|
|
|
|
|
+ if source_ext in video_extensions:
|
|
|
|
|
+ # 对于视频输入,设置项目名和实验名以确保输出路径
|
|
|
|
|
+ if not predict_kwargs.get('project'):
|
|
|
|
|
+ predict_kwargs['project'] = 'runs/detect'
|
|
|
|
|
+ if not predict_kwargs.get('name'):
|
|
|
|
|
+ predict_kwargs['name'] = 'predict'
|
|
|
|
|
+
|
|
|
results = model.predict(**predict_kwargs)
|
|
results = model.predict(**predict_kwargs)
|
|
|
logging.info("模型预测完成")
|
|
logging.info("模型预测完成")
|
|
|
|
|
|
|
@@ -458,27 +472,63 @@ def yolov12_predict(params: PredictParams):
|
|
|
except (FileNotFoundError, subprocess.SubprocessError) as e:
|
|
except (FileNotFoundError, subprocess.SubprocessError) as e:
|
|
|
logging.error(f"ffmpeg不可用: {e}")
|
|
logging.error(f"ffmpeg不可用: {e}")
|
|
|
|
|
|
|
|
- # 如果ffmpeg不可用,尝试使用OpenCV
|
|
|
|
|
- try:
|
|
|
|
|
- import cv2
|
|
|
|
|
- cap = cv2.VideoCapture(video_file)
|
|
|
|
|
- fps = cap.get(cv2.CAP_PROP_FPS)
|
|
|
|
|
- width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
|
|
|
- height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
|
|
|
-
|
|
|
|
|
- # 尝试不同的编码器
|
|
|
|
|
- fourcc_options = ['H264', 'avc1', 'mp4v']
|
|
|
|
|
- out = None
|
|
|
|
|
-
|
|
|
|
|
- for fourcc in fourcc_options:
|
|
|
|
|
- try:
|
|
|
|
|
- codec = cv2.VideoWriter_fourcc(*fourcc)
|
|
|
|
|
- out = cv2.VideoWriter(output_mp4, codec, fps, (width, height))
|
|
|
|
|
|
|
+ # 如果ffmpeg不可用,尝试使用OpenCV
|
|
|
|
|
+ try:
|
|
|
|
|
+ import cv2
|
|
|
|
|
+ cap = cv2.VideoCapture(video_file)
|
|
|
|
|
+ fps = cap.get(cv2.CAP_PROP_FPS)
|
|
|
|
|
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
|
|
|
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
|
|
|
+
|
|
|
|
|
+ # 强制使用H264编码器,如果失败则使用XVID
|
|
|
|
|
+ fourcc_options = ['H264', 'avc1']
|
|
|
|
|
+ out = None
|
|
|
|
|
+
|
|
|
|
|
+ for fourcc in fourcc_options:
|
|
|
|
|
+ try:
|
|
|
|
|
+ codec = cv2.VideoWriter_fourcc(*fourcc)
|
|
|
|
|
+ out = cv2.VideoWriter(output_mp4, codec, fps, (width, height))
|
|
|
|
|
+ if out.isOpened():
|
|
|
|
|
+ logging.info(f"使用OpenCV编码器 {fourcc}")
|
|
|
|
|
+ break
|
|
|
|
|
+ except:
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ # 如果H264和avc1都失败,使用XVID生成AVI,然后用ffmpeg转换
|
|
|
|
|
+ if not out or not out.isOpened():
|
|
|
|
|
+ logging.warning("H264编码器不可用,使用XVID生成AVI")
|
|
|
|
|
+ temp_avi = video_file.rsplit('.', 1)[0] + '_temp.avi'
|
|
|
|
|
+ xvid_codec = cv2.VideoWriter_fourcc(*'XVID')
|
|
|
|
|
+ out = cv2.VideoWriter(temp_avi, xvid_codec, fps, (width, height))
|
|
|
|
|
+
|
|
|
if out.isOpened():
|
|
if out.isOpened():
|
|
|
- logging.info(f"使用OpenCV编码器 {fourcc}")
|
|
|
|
|
- break
|
|
|
|
|
- except:
|
|
|
|
|
- continue
|
|
|
|
|
|
|
+ while cap.isOpened():
|
|
|
|
|
+ ret, frame = cap.read()
|
|
|
|
|
+ if not ret:
|
|
|
|
|
+ break
|
|
|
|
|
+ out.write(frame)
|
|
|
|
|
+
|
|
|
|
|
+ cap.release()
|
|
|
|
|
+ out.release()
|
|
|
|
|
+
|
|
|
|
|
+ # 尝试用ffmpeg将AVI转换为MP4
|
|
|
|
|
+ try:
|
|
|
|
|
+ cmd = [
|
|
|
|
|
+ 'ffmpeg', '-i', temp_avi,
|
|
|
|
|
+ '-c:v', 'libx264',
|
|
|
|
|
+ '-preset', 'ultrafast',
|
|
|
|
|
+ '-crf', '28',
|
|
|
|
|
+ '-pix_fmt', 'yuv420p',
|
|
|
|
|
+ '-y', output_mp4
|
|
|
|
|
+ ]
|
|
|
|
|
+ result = subprocess.run(cmd, capture_output=True, text=True)
|
|
|
|
|
+ if result.returncode == 0:
|
|
|
|
|
+ os.remove(temp_avi)
|
|
|
|
|
+ logging.info(f"通过AVI中转成功生成MP4: {output_mp4}")
|
|
|
|
|
+ else:
|
|
|
|
|
+ logging.error(f"AVI转MP4失败: {result.stderr}")
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ logging.error(f"ffmpeg不可用,保持AVI格式: {e}")
|
|
|
|
|
|
|
|
if out and out.isOpened():
|
|
if out and out.isOpened():
|
|
|
while cap.isOpened():
|
|
while cap.isOpened():
|