目录
前言
通过slowfast的官网可以知道,使用ffmpeg将视频先裁剪15分钟的视频,然后将15分钟的视频转化为图片帧。再使用detectron2的faster rcnn检测所有图片,再用python将检测结果整理为via(VGG Image Annotator)可是识别的csv文件。
一,ffmpeg 自动裁剪
我们需要将视频剪辑为15分钟的视频,这里和ava不同,ava要的是视频第15分钟到30分钟的,但是我们这里就不用了,直接裁剪0到15分钟的视频。
然后是将15分钟的视频切割成帧,我这里是每秒一帧。
1.1 目录结构
首先创建四个文件夹
ffmpeg_code
:存放ffmpeg代码
myFrames
:存放视频裁剪后的图片帧
myVideo
:原始视频
myVideo15mins
:剪辑后的视频(15分钟)
1.2 cutVideoToImage.sh
在ffmpeg_code
下创建cutVideoToImage.sh
这个代码就是自动把视频裁剪,然后再裁剪图片
代码如下(有注释):
#这个shell是将视频先剪辑为15分钟视频,然后再将15分钟的视频按照每秒1帧剪辑为图片
#开始之前 先清除 myFrames下的内容
rm -rf /home/lxn/yf_videos/myFrames
#这里是剪辑视频,和ava官网不同,这里直接剪辑前15分钟的视频
videoName="eight.mp4"
ffmpeg -ss 0 -t 901 -i "../myVideo/${videoName}" "../myVideo15mins/${videoName}"
#切割图片,每秒1帧
IN_DATA_DIR="../myVideo15mins"
OUT_DATA_DIR="../myFrames"
if [[ ! -d "${OUT_DATA_DIR}" ]]; then
echo "${OUT_DATA_DIR} doesn't exist. Creating it.";
mkdir -p ${OUT_DATA_DIR}
fi
for video in $(ls -A1 -U ${IN_DATA_DIR}/*)
do
video_name=${video##*/}
if [[ $video_name = *".webm" ]]; then
video_name=${video_name::-5}
else
video_name=${video_name::-4}
fi
out_video_dir=${OUT_DATA_DIR}/${video_name}/
mkdir -p "${out_video_dir}"
out_name="${out_video_dir}/${video_name}_%06d.jpg"
ffmpeg -i "${video}" -r 1 -q:v 1 "${out_name}"
done
#需要裁剪的图片移动到指定文件夹,用于faster rcnn自动框人
#首先清理指定文件夹里存在的图片
rm -rf /home/lxn/0yangfan/detectron2_repo/img/original
#存放检测结果的文件也需要清空
#rm -rf /home/lxn/0yangfan/detectron2_repo/img/detection
if [[ videoName = *".webm" ]]; then
videoName=${videoName::-5}
else
videoName=${videoName::-4}
fi
cp -r "../myFrames/${videoName}" /home/lxn/0yangfan/detectron2_repo/img/original
在代码的最后一句:
cp -r "../myFrames/${videoName}" /home/lxn/0yangfan/detectron2_repo/img/original
这个表示将最后裁剪的图片放在/home/lxn/0yangfan/detectron2_repo/img/original
目录下,这个img/original目录是自己创建的目录。
1.2 myVideo
在myVideo
下存放原始视频,就是我们自己收集的数据集视频
1.3 myVideo15mins
在myVideo15mins
中存放剪辑的视频(代码中自动剪辑存储)
1.5 myFrames
myFrames
中存放剪辑的图片
1.6 运行
进入到目录:/ffmpeg_code
中,然后执行如下命令:
sudo sh cutVideoToImage.sh
会花一点时间(顺便去背背单词)
1.7 查看结果
最后结果,是要在/home/lxn/0yangfan/detectron2_repo/img/original
下查看,如果这里出现了903张剪辑好的图片,说明成功了。
二,detectron2中的faster rcnn检测
第一部分,我们已经将视频转化为图片,这一部分将使用detectron2中的faster rcnn 将全部图片进行检测。
2.1 img
在目录/detectron2_repo/
下创建img
目录,这个目录用来存放原始图片,处理后的图片,csv文件。
original
:用于存放原始图片的目录(里面的图片是ffmpeg裁剪出来的,然后再复制到这个目录下的)。
detection
用于存放检测后的图片
detection.csv
:是将最后的检测结果转换为via可以识别的csv文件。
2.2 myvia.py
在目录/detectron2_repo/demo/
下创建myvia.py这个文件:
代码如下(有注释):
#Copyright (c) Facebook, Inc. and its affiliates.
import argparse
import glob
import multiprocessing as mp
import os
import time
import cv2
import tqdm
import os
from detectron2.config import get_cfg
from detectron2.data.detection_utils import read_image
from detectron2.utils.logger import setup_logger
from predictor import VisualizationDemo
import csv
import pandas as pd #导入pandas包
import re
# constants
WINDOW_NAME = "COCO detections"
def setup_cfg(args):
# load config from file and command-line arguments
cfg = get_cfg()
# To use demo for Panoptic-DeepLab, please uncomment the following two lines.
# from detectron2.projects.panoptic_deeplab import add_panoptic_deeplab_config # noqa
# add_panoptic_deeplab_config(cfg)
cfg.merge_from_file(args.config_file)
cfg.merge_from_list(args.opts)
# Set score_threshold for builtin models
cfg.MODEL.RETINANET.SCORE_THRESH_TEST = args.confidence_threshold
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = args.confidence_threshold
cfg.MODEL.PANOPTIC_FPN.COMBINE.INSTANCES_CONFIDENCE_THRESH = args.confidence_threshold
cfg.freeze()
return cfg
def get_parser():
parser = argparse.ArgumentParser(description="Detectron2 demo for builtin configs")
parser.add_argument(
"--config-file",
default="configs/quick_schedules/mask_rcnn_R_50_FPN_inference_acc_test.yaml",
metavar="FILE",
help="path to config file",
)
parser.add_argument("--webcam", action="store_true", help="Take inputs from webcam.")
parser.add_argument("--video-input", help="Path to video file.")
parser.add_argument(
"--input",
nargs="+",
help="A list of space separated input images; "
"or a single glob pattern such as 'directory/*.jpg'",
)
parser.add_argument(
"--output",
help="A file or directory to save output visualizations. "
"If not given, will show output in an OpenCV window.",
)
parser.add_argument(
"--confidence-threshold",
type=float,
default=0.5,
help="Minimum score for instance predictions to be shown",
)
parser.add_argument(
"--opts",
help="Modify config options using the command-line 'KEY VALUE' pairs",
default=[],
nargs=argparse.REMAINDER,
)
return parser
if __name__ == "__main__":
mp.set_start_method("spawn", force=True)
args = get_parser().parse_args()
setup_logger(name="fvcore")
logger = setup_logger()
logger.info("Arguments: " + str(args))
#图片的输入和输出文件夹
imgOriginalPath = './img/original/'
imgDetectionPath= './img/detection'
# 读取文件下的图片名字
for i,j,k in os.walk(imgOriginalPath):
# k 存储了图片的名字
#imgInputPaths用于存储图片完整地址
#使用.sort()防止乱序
k.sort()
imgInputPaths = k
countI=0
for namek in k:
#循环将图片的完整地址加入imgInputPaths中
imgInputPath = imgOriginalPath + namek
imgInputPaths[countI]=imgInputPath
countI = countI + 1
break
#修改args里输入图片的里路径
args.input = imgInputPaths
#修改args里输出图片的路径
args.output = imgDetectionPath
cfg = setup_cfg(args)
demo = VisualizationDemo(cfg)
#创建csv
csvFile = open("./img/detection.csv", "w+",encoding="gbk")
#创建写的对象
CSVwriter = csv.writer(csvFile)
#先写入columns_name
#写入列的名称
CSVwriter.writerow(["filename","file_size","file_attributes","region_count","region_id","region_shape_attributes","region_attributes"])
#写入多行用CSVwriter
#写入多行
#CSVwriter.writerows([[1,a,b],[2,c,d],[3,d,e]])
#csvFile.close()
#https://blog.csdn.net/xz1308579340/article/details/81106310?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-3.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-3.control
if args.input:
if len(args.input) == 1:
args.input = glob.glob(os.path.expanduser(args.input[0]))
assert args.input, "The input path(s) was not found"
for path in tqdm.tqdm(args.input, disable=not args.output):
# use PIL, to be consistent with evaluation
img = read_image(path, format="BGR")
start_time = time.time()
predictions,visualized_output = demo.run_on_image(img)
#只要检测结果是人的目标结果
mask = predictions["instances"].pred_classes == 0
pred_boxes = predictions["instances"].pred_boxes.tensor[mask]
#在路径中正则匹配图片的名称
ImgNameT = re.findall(r'[^\\/:*?"<>|\r\n]+$', path)
ImgName = ImgNameT[0]
#获取图片大小(字节)
ImgSize = os.path.getsize(path)
#下面的为空(属性不管)
img_file_attributes="{"+"}"
#每张图片检测出多少人
img_region_count = len(pred_boxes)
#region_id表示在这张图中,这是第几个人,从0开始数
region_id = 0
#region_attributes 为空
img_region_attributes = "{"+"}"
#循环图中检测出的人的坐标,然后做修改,以适应via
for i in pred_boxes:
#将i中的数据类型转化为可以用的数据类型(list)
iList = i.cpu().numpy().tolist()
#数据取整,并将坐标数据放入到
img_region_shape_attributes = {"\"name\"" : "\"rect\"" , "\"x\"" : int(iList[0]) , "\"y\"" : int(iList[1]) ,"\"width\"" : int(iList[2]-iList[0]) , "\"height\"" : int(iList[3]-iList[1]) }
#将信息写入csv中
CSVwriter.writerow([ImgName,ImgSize,'"{}"',img_region_count,region_id,str(img_region_shape_attributes),'"{}"'])
region_id = region_id + 1
logger.info(
"{}: {} in {:.2f}s".format(
path,
"detected {} instances".format(len(predictions["instances"]))
if "instances" in predictions
else "finished",
time.time() - start_time,
)
)
if args.output:
if os.path.isdir(args.output):
assert os.path.isdir(args.output), args.output
out_filename = os.path.join(args.output, os.path.basename(path))
else:
assert len(args.input) == 1, "Please specify a directory with args.output"
out_filename = args.output
visualized_output.save(out_filename)
else:
cv2.namedWindow(WINDOW_NAME, cv2.WINDOW_NORMAL)
cv2.imshow(WINDOW_NAME, visualized_output.get_image()[:, :, ::-1])
if cv2.waitKey(0) == 27:
break # esc to quit
#关闭csv
csvFile.close()
2.3 运行
进入到目录:/detectron2_repo
中,输入命令:
python3 ./demo/myvia.py --config-file configs/COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml --opts MODEL.WEIGHTS detectron2://COCO-Detection/faster_rcnn_R_50_FPN_3x/137849458/model_final_280758.pkl
2.4 结果展示
检测结果图
检测后的csv文件
三,via标注
最后,我们要把上一部分生成的csv文件导入到via中,开始之前,需要做一些准备。
3.1 csv文件修改(去掉全部单引号)
在文件夹detectron2_repo/img/
中的detection.csv
还不能直接用,要做一点点修改,修改如下:
使用文本编辑器打开detection.csv
要做的修改就是将这里面的全部 ’ 去掉(去掉全部的单引号)
3.2 在via中导入图片
打开via
选中原始图图片
导入成功后的样子
3.2 导入csv文件
按照下图方式选中detection.csv
文件
最后的结果展示