【ffmpeg裁剪视频faster rcnn自动检测 via】全自动实现ffmpeg将视频切割为图片帧,再使用faster rcnn将图片中的人检测出来,最后将检测结果转化为via可识别的csv格式

前言

B站讲解视频

通过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文件
在这里插入图片描述
最后的结果展示
在这里插入图片描述

FFmpeg是一个强大的跨平台命令行工具,用于处理多媒体文件,包括音频、视频流的转换、编码、解码等。当使用FFmpeg图片序列转换成视频时,如果速度较慢,可能是以下几个原因导致的: 1. **图片分辨率高或数量大**:每张图片的质量和尺寸都会影响到转换的时间。如果图片分辨率非常高,或者是大量的图片叠加在一起,处理时间会显著增加。 2. **编码设置**:FFmpeg提供了多种编码格式供选择,不同的编码器性能差异较大。比如H.264编码通常比 MJPEG 或 WMV 更快,但质量可能会有所牺牲。调整合适的编码参数可以提高效率。 3. **硬件限制**:如果你的计算机CPU或内存不足,处理大量图片视频数据会显得吃力。使用更快的处理器或增加内存可以加快转换速度。 4. **命令行选项优化**:如果没有正确设置如并行处理或多线程(`-threads` 参数),FFmpeg可能会按单线程运行,这会限制了它的处理能力。 5. **I/O瓶颈**:如果输入图片存储位置离系统读取远,或者磁盘IO速度慢,也可能会影响转换速度。 为了改善这种情况,你可以尝试优化命令,例如采用多线程,调整编码格式和参数,以及检查系统的资源利用情况。这里提供一个基本的FFmpeg命令示例,你可以作为起点进行优化: ```bash ffmpeg -framerate <率> -i input_%d.jpg -c:v libx264 -preset faster output.mp4 ``` 其`<率>`是你需要的输出视频率,`input_%d.jpg`代表你的图片序列文件名规则(%d表示数字序号)。记得替换具体的参数值,并查看FFmpeg文档了解更多详细选项。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值