计算机视觉新手求助:关联图像与JSON标注及无YOLO视频人类活动检测
一、关联JSON标注文件与图像
1. 先解析JSON标注结构
绝大多数图像标注JSON(比如COCO、LabelMe格式)都会包含两个核心部分:
images字段:存储图像的元数据,比如文件名、图像ID、宽高信息annotations字段:存储每个标注的细节,比如对应图像ID、bounding box坐标、类别标签
用Python快速加载并查看结构:
import json # 加载JSON文件 with open("your_annotations.json", "r", encoding="utf-8") as f: annot_data = json.load(f) # 查看图像列表第一条数据 print(annot_data["images"][0]) # 查看标注列表第一条数据 print(annot_data["annotations"][0])
2. 匹配图像与标注
根据JSON里的关联键(通常是image_id)建立映射:
- 先创建图像ID到文件路径的字典:
image_map = {img["id"]: img["file_name"] for img in annot_data["images"]}
- 遍历所有标注,找到对应图像:
for annot in annot_data["annotations"]: img_filename = image_map[annot["image_id"]] bbox = annot["bbox"] # 通常是[x, y, width, height]格式 category = annot["category_id"] # 后续可以加载图像并绘制bbox
3. 可视化验证
用OpenCV或PIL绘制标注,确认关联正确:
import cv2 img_path = f"your_image_dir/{img_filename}" img = cv2.imread(img_path) # 转换bbox坐标为(x1, y1, x2, y2) x1, y1, w, h = bbox x2, y2 = x1 + w, y1 + h # 绘制红色bounding box cv2.rectangle(img, (int(x1), int(y1)), (int(x2), int(y2)), (0, 0, 255), 2) # 显示图像 cv2.imshow("Annotated Image", img) cv2.waitKey(0) cv2.destroyAllWindows()
二、不使用YOLO实现视频人类活动检测与Bounding Box标注
方案1:OpenCV原生工具(轻量易上手)
适合简单场景(比如固定摄像头、光线充足):
- 人体检测:用HOG+SVM检测器,OpenCV内置预训练模型:
import cv2 # 初始化HOG人体检测器 hog = cv2.HOGDescriptor() hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) # 读取视频 cap = cv2.VideoCapture("input_video.mp4") 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)) # 准备输出视频 out = cv2.VideoWriter("output.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (width, height)) while cap.isOpened(): ret, frame = cap.read() if not ret: break # 检测人体,返回bbox和置信度 bboxes, weights = hog.detectMultiScale(frame, winStride=(4, 4), padding=(8, 8), scale=1.05) # 绘制bbox for (x, y, w, h) in bboxes: cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(frame, "Person", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) out.write(frame) cv2.imshow("Detection", frame) if cv2.waitKey(1) & 0xFF == ord("q"): break cap.release() out.release() cv2.destroyAllWindows()
- 活动检测:结合帧间差分或光流法判断动作:
- 帧间差分:计算相邻帧的灰度差,阈值化后分析人体区域的变化,判断是否在移动
- Farneback光流:计算帧间像素运动向量,统计人体区域内的光流方向和大小,区分行走、站立等动作
方案2:预训练目标检测+动作识别模型(精度更高)
适合复杂场景,用PyTorch/TensorFlow的预训练模型:
- 人体检测:用Faster R-CNN或SSD的预训练模型,比如torchvision内置的模型:
import torch import torchvision from torchvision.transforms import functional as F import cv2 # 加载预训练Faster R-CNN模型 model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True) model.eval() # 视频处理流程和上面类似,逐帧转换为张量输入模型 cap = cv2.VideoCapture("input_video.mp4") while cap.isOpened(): ret, frame = cap.read() if not ret: break # 转换图像格式 img = F.to_tensor(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) with torch.no_grad(): predictions = model([img]) # 提取人体bbox(类别ID=1对应COCO数据集的人) for box, score, label in zip(predictions[0]["boxes"], predictions[0]["scores"], predictions[0]["labels"]): if label == 1 and score > 0.5: x1, y1, x2, y2 = box.numpy().astype(int) cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 0, 0), 2) cv2.imshow("Detection", frame) if cv2.waitKey(1) & 0xFF == ord("q"): break
- 活动检测:用预训练的动作识别模型(比如TSM、SlowFast),截取人体区域的连续帧输入模型,得到活动类别(比如“walking”“sitting”),再和bbox关联标注。
内容的提问来源于stack exchange,提问作者Jin0507
相关产品推荐
相关产品推荐

