Python 实现图片、视频标注打标完整方案
日常常用图像标注、视频帧标注、目标框选、分类标签、关键点标注,下面分轻量脚本、开源标注工具二次开发、AI自动标注三类实现,附带可直接运行代码。
一、技术选型说明
| | |
|---|
| opencv-python | |
| cv2 | |
| labelme | |
| ultralytics(YOLO) | |
| tkinter/flet/pyqt | |
二、环境一键安装
# 基础图像处理
pip install opencv-python pillow numpy
# YOLO自动标注
pip install ultralytics
# 专业标注工具
pip install labelme labelImg
三、1. 简易手动图片标注(画框+保存标签)
功能:鼠标拖拽画目标框、输入类别、保存标注JSON
import cv2
import json
import os
img_path = "test.jpg"
save_label_path = "label.json"
img = cv2.imread(img_path)
img_copy = img.copy()
drawing = False
x1, y1, x2, y2 = 0, 0, 0, 0
label_data = {"shapes": [], "imagePath": img_path}
# 鼠标回调
defmouse_event(event, x, y, flags, param):
global x1, y1, x2, y2, drawing, img_copy
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
x1, y1 = x, y
elif event == cv2.EVENT_MOUSEMOVE:
if drawing:
temp_img = img.copy()
cv2.rectangle(temp_img, (x1, y1), (x, y), (0,255,0), 2)
cv2.imshow("图片标注", temp_img)
elif event == cv2.EVENT_LBUTTONUP:
drawing = False
x2, y2 = x, y
cv2.rectangle(img_copy, (x1, y1), (x2, y2), (0,255,0), 2)
cv2.imshow("图片标注", img_copy)
# 输入标签
cls = input("输入目标类别:")
shape = {
"label": cls,
"points": [[x1,y1],[x2,y2]]
}
label_data["shapes"].append(shape)
cv2.namedWindow("图片标注")
cv2.setMouseCallback("图片标注", mouse_event)
cv2.imshow("图片标注", img)
whileTrue:
key = cv2.waitKey(1)
# ESC 退出,S保存
if key == 27:
break
if key == ord("s"):
with open(save_label_path, "w", encoding="utf-8") as f:
json.dump(label_data, f, ensure_ascii=False, indent=2)
print("标注已保存至", save_label_path)
cv2.destroyAllWindows()
四、2. 视频逐帧抽帧标注
先把视频拆成图片,再复用上面图片标注逻辑
import cv2
import os
defvideo2frame(video_path, save_img_dir, interval=10):
"""
视频抽帧
:param interval: 每隔多少帧保存一张
"""
os.makedirs(save_img_dir, exist_ok=True)
cap = cv2.VideoCapture(video_path)
frame_idx = 0
save_idx = 0
whileTrue:
ret, frame = cap.read()
ifnot ret:
break
if frame_idx % interval == 0:
save_name = f"frame_{save_idx}.jpg"
cv2.imwrite(os.path.join(save_img_dir, save_name), frame)
save_idx += 1
frame_idx += 1
cap.release()
print(f"抽帧完成,共保存 {save_idx} 张图片")
# 使用
video2frame("test.mp4", "video_frames", interval=15)
抽帧后批量调用图片标注代码即可完成视频标注。
五、3. YOLO AI自动批量打标(大批量提速首选)
自动识别目标、生成YOLO标签,人工微调即可
from ultralytics import YOLO
import os
model = YOLO("yolov8n.pt") # 加载预训练模型
img_dir = "imgs"
save_label_dir = "labels"
os.makedirs(save_label_dir, exist_ok=True)
for img_name in os.listdir(img_dir):
if img_name.lower().endswith((".jpg",".png",".jpeg")):
img_path = os.path.join(img_dir, img_name)
results = model(img_path)
# 生成yolo格式txt标注
txt_name = os.path.splitext(img_name)[0] + ".txt"
txt_path = os.path.join(save_label_dir, txt_name)
with open(txt_path, "w") as f:
for box in results[0].boxes:
cls_id = int(box.cls[0])
x,y,w,h = box.xywhn[0].tolist()
f.write(f"{cls_id}{x:.6f}{y:.6f}{w:.6f}{h:.6f}\n")
print("AI自动标注全部完成")
六、4. 调用专业可视化标注工具(最简单商用级)
4.1 LabelImg 框标注(VOC/YOLO格式)
# 直接命令启动
labelImg
- 保存
VOC(xml)、YOLO(txt)、COCO(json) 标准数据集格式
4.2 LabelMe 多边形/关键点/分割标注
labelme
适合不规则物体、关键点、语义分割标注,输出JSON标签。
七、5. 视频AI自动标注并保存标注视频
识别目标并实时画框输出带标注的新视频
from ultralytics import YOLO
import cv2
model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("test.mp4")
fps = int(cap.get(cv2.CAP_PROP_FPS))
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 保存标注后视频
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out = cv2.VideoWriter("labeled_video.mp4", fourcc, fps, (w,h))
while cap.isOpened():
ret, frame = cap.read()
ifnot ret:
break
# AI推理画框
res = model.track(frame, persist=True)
annotated_frame = res[0].plot()
out.write(annotated_frame)
cv2.imshow("视频自动标注", annotated_frame)
if cv2.waitKey(1) & 0xFF == 27:
break
cap.release()
out.release()
cv2.destroyAllWindows()
print("标注视频保存完成")
八、常用标注格式说明
- LabelMe json:多边形、关键点、标签信息
九、场景选型建议
- 少量图片临时标注 → 直接用
LabelImg/LabelMe - 大批量图片/视频 → YOLO自动预标注+人工修正
- 做成桌面标注系统 → Flet/PyQt + OpenCV封装界面