learn-yolo/11.应用-视频马赛克.py

110 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
from ultralytics import YOLO
from moviepy import VideoFileClip # 用于处理音频(仅视频文件需要)
def apply_gaussian_blur(region, blur_strength=25):
"""对目标区域应用高斯模糊"""
return cv2.GaussianBlur(region, (blur_strength, blur_strength), 0)
def process_video(input_video, output_video, model, blur_strength=25, target_classes=None):
"""处理视频并应用高斯模糊"""
# 提取原始视频的音频(仅用于视频文件)
original_clip = VideoFileClip(input_video)
audio = original_clip.audio
# 读取视频
cap = cv2.VideoCapture(input_video)
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 创建临时无音频视频
temp_output = "temp_blurred_no_audio.mp4"
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(temp_output, fourcc, fps, (width, height))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# YOLO 检测
results = model(frame)
# 遍历检测结果
for box in results[0].boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0]) # 检测框坐标
cls_id = int(box.cls.item()) # 类别ID
# 如果指定了目标类别,只模糊这些类别
if target_classes is None or cls_id in target_classes:
# 提取检测区域并模糊
roi = frame[y1:y2, x1:x2]
blurred_roi = apply_gaussian_blur(roi, blur_strength)
frame[y1:y2, x1:x2] = blurred_roi
# 写入输出视频
out.write(frame)
# 显示实时结果(可选)
cv2.imshow("YOLO Blur Detection", frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
# 合并音频(仅视频文件需要)
blurred_clip = VideoFileClip(temp_output)
final_clip = blurred_clip.with_audio(audio)
final_clip.write_videofile(output_video, codec="libx264", audio_codec="aac")
# 删除临时文件(可选)
import os
os.remove(temp_output)
def main():
# 加载 YOLO 模型(可以是 yolov8n.pt, yolov8s.pt 等)
model = YOLO("runs/detect/train4/weights/best.pt") # 替换成你的模型
# 输入视频文件(如果是摄像头,设为 0
input_video = "resources/input1.mp4" # 或 0摄像头
output_video = "output_blurred.mp4"
# 设置高斯模糊强度(越大越模糊)
blur_strength = 79
# 指定要模糊的类别可选None 表示模糊所有检测到的目标)
# COCO 数据集类别0: person, 1: bicycle, 2: car, ..., 参见 https://cocodataset.org
target_classes = [0] # 示例只模糊人person
if input_video == 0:
# 摄像头实时检测(无音频)
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# YOLO 检测 + 模糊
results = model(frame)
for box in results[0].boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
cls_id = int(box.cls.item())
if target_classes is None or cls_id in target_classes:
roi = frame[y1:y2, x1:x2]
frame[y1:y2, x1:x2] = apply_gaussian_blur(roi, blur_strength)
cv2.imshow("Live Blur Detection", frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
else:
# 处理视频文件(保留音频)
process_video(input_video, output_video, model, blur_strength, target_classes)
if __name__ == "__main__":
main()