python实现视频抽帧,文件批量操作,文件批量处理(数据集制作的工具箱)

这篇具有很好参考价值的文章主要介绍了python实现视频抽帧,文件批量操作,文件批量处理(数据集制作的工具箱)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据集制作的工具箱

目录

  1. 环境准备
  2. 数据集制作
  3. 文件批量重命名
  4. 文件批量移动
  5. 将文件批量按照一定格式进行重命名
  6. 修改xml文件内容的方法
  7. Pathlib库的常用接口

引言

在计算机视觉项目中,文件批量操作和文件批量预处理是必不可少的步骤。它们涉及处理大量的图像文件,包括读取、处理、保存和预处理。本文将介绍一些常见的技术和方法,以帮助您在计算机视觉项目中有效地进行文件批量操作和文件批量预处理。

环境准备

from pathlib import Path, PurePath
import xml.etree.ElementTree as ET
from typing import Union
import numpy as np
from tqdm import tqdm
import time
import cv2
import os

数据集制作

人工智能就是有多少人工产生多少智能,在计算机视觉项目中,数据集至关重要,下面是如何使用视频抽帧技术实现数据集的制作。以下代码中_videoPlay函数是实时显示导入的视频,CutVideo函数实现手动抽帧,在显示时按c键则抽取当前帧,按Esc键关闭视频。ExtractAll函数是自动抽帧功能,frameGap参数是隔多少帧进行自动抽取。

class ExtractImg(object):
    def __init__(self, videopath: Path, savepath: Path, delay: int = 1) -> None:
        self.spath = savepath
        self.vpath = videopath
        self.delay = delay
        cv2.namedWindow("cv", cv2.WINDOW_NORMAL)
        cv2.resizeWindow("cv", 640, 480)
        self.cap = cv2.VideoCapture(str(self.vpath))
        self._timeflag = 0
        if not savepath.exists():
            os.mkdir(Path(savepath))

    def _videoPlay(self, size: list) -> None:
        self.cap.set(3, size[0])
        self.cap.set(4, size[1])
        while self.cap.isOpened():
            ret, frame = self.cap.read()
            # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            cv2.imshow("cv", frame)
            if cv2.waitKey(self.delay) & 0xFF == ord('c'):
                cv2.imwrite(str(PurePath.joinpath(self.spath,
                                                  "{}.jpg".format(str(time.time())))), frame)
                print("保存成功")
                time.sleep(1)
            elif cv2.waitKey(self.delay) & 0xFF == 27:
                break

    def ExtractAll(self, frameGap: int = 3) -> None:
        """
        这是将视频流中的帧全部抽出
        :frame: 跳帧
        :return:
        """
        while self.cap.isOpened():
            self._timeflag += 1

            ret, frame = self.cap.read()
            if ret:
                cv2.imshow("cv", frame)
                if self._timeflag % frameGap == 0:
                    cv2.imwrite(str(PurePath.joinpath(self.spath,
                                                      "{}.jpg".format(str(time.time())))), frame)
                    print("保存成功")
            if (cv2.waitKey(self.delay) & 0xFF == 27) or not ret:
                break
        cv2.destroyAllWindows()
        self.cap.release()
        self._timeflag = 0

    def CutVideo(self) -> None:
        """
        这是手动抽帧
        :return:
        """
        ifm = input("文件中已经存在{}张图片,是否有继续添加"
                    "(Y or N):".format(len(os.listdir(self.spath))))
        if self.spath.exists() and ifm == 'Y':
            self._videoPlay(size=[640, 480])
        elif self.spath.exists() and ifm == 'N':
            return None
        else:
            print("\n请输入Y(yes)或者N(no)")
        cv2.destroyAllWindows()
        self.cap.release()

文件批量重命名

将文件夹下的图片进行升序的重命名。

  def statistics(path: Union[str, Path], dstpath: Union[Path, str], count: int = 0, random: bool = False) -> None:
        """
        这是存放图片的文件夹安升序重命名
        :param path:需要重命名的文件文件
        :param count:观察图片总数添加使用
        """
        assert isinstance(path, (Path, str)), print("请输入的路径")
        l = os.listdir(str(path))
        if not Path.exists(dstpath):
            Path.mkdir(dstpath)
        # l = sorted(l)
        print(l)
        # print(l)
        print("存在文件{}张!".format(len(l)))
        if random:
            np.random.shuffle(l)
        # print(l)
        # 将保存图片文件中的图片按照升序的方法重命名

        suffix = Path(l[0]).suffix
        for file in tqdm(l):
            src = PurePath.joinpath(path, file)
            dst = PurePath.joinpath(dstpath, Path(str(count + int(Path(file).stem))).with_suffix(suffix))
            os.rename(src, dst)

文件批量移动

下面的是将文件批量按照一定规则挑选出来放到目标文件夹下。

    def choosen(src: Union[str, Path] , folder: Union[Path,str] ,dst: Union[str, Path] , suffix: str) -> None:
        """
        1.将xml/jpg文件夹中的文件名字拿出来并且在jpg/xml对应的文件夹中将名称相同的文件挑出来
        2.将文件夹中的文件随取出
        :param xmlsrc:目标xml文件
        :param imgsrc:frameImg文件
        :param dst:根据xml挑选出的img文件
        :return: None
        """
        # l = os.listdir(str(xmlsrc))
        if not isinstance(folder,Path):
            pa = Path(folder)
        if not isinstance(src,Path):
            l = Path(src)

        # parent = src.parent
        for i in l.iterdir():
            file = Path(i.name).with_suffix(suffix)
            (pa / file).rename(Path(dst) / file)

将文件批量按照一定格式进行重命名

下面将文件按照5位数字的格式进行重命名 1.jpg->00001.jpg

    def batchrenames(src: Union[str, Path], dst: Union[str, Path], sorted: bool = False) -> None:
        """
        进行特定格式的重命名
        :param src:原文件
        :param dst: 存储文件
        :param sorted: 是否已经有顺序,若有学按照1.jpg ->00001.jpg
        :return: None
        """

        d = {1: "0000",  # 这是命名格式的字典
             2: "000",
             3: "00",
             4: "0",
             5: ""}
        l = os.listdir(src)
        suffix = Path(l[0]).suffix
        l.sort(key=lambda x: int(x.split('.')[0]))
        if sorted:
            for obj in tqdm(l):
                old = PurePath.joinpath(src, obj)
                new = PurePath.joinpath(dst, d[len(obj.split('.')[0])] + obj.split('.')[0] + suffix)
                os.rename(old, new)
        else:
            # for c, i in tqdm(enumerate(l)):
            pass

修改xml文件内容的方法

这是修改xml文件内容的代码。

    def revampXml(xml_path: Union[Path, str], update_content: str) -> None:
        """
        这是一个修改xml文件内容的方法,将xml文件爱中的类别改称另一个类别
        :param xml_path: 存放xml文件的路径
        :param xml_dw: xpath关键字
        :param update_content: 更新的内容
        :return:None
        """
        # 打开xml文档
        if not isinstance(xml_path, Path):
            xml_path = Path(xml_path)
        for i in tqdm(xml_path.iterdir()):
            xmlfile = xml_path / f"{i}"
            doc = ET.parse(xmlfile)
            root = doc.getroot()
            # 查找修改路劲
            for obj in root.iter("object"):
                sub1 = obj.find("name")
                if sub1.text == "motorboat":
                    # 修改标签内容
                    sub1.text = update_content
                    # 保存修改
                    doc.write(xmlfile)

Pathlib库以及os库的常用文件操作API

pathlib是 标准库之一,用于操作文件系统路径。该库可以方便地进行路径的拼接、文件/目录的创建、复制/移动、删除等操作。

功能描述 pathlib操作 os及os.path操作
获得绝对路径 Path.resolve() os.path.abspath()
修改文件权限和时间戳 Path.chmod() os.chmod()
创建目录 Path.mkdir() os.mkdir()
文件或文件夹重命名,如果路径不同,会移动并重新命名 Path.rename() os.rename()
文件或文件夹重命名,如果路径不同,会移动并重新命名,如果存在,则破坏现有目标 Path.replace() os.replace()
删除目录 Path.rmdir() os.rmdir()
删除一个文件 Path.unlink() os.remove()
删除一个文件 Path.unlink() os.unlink()
获得当前工作目录 Path.cwd() os.getcwd()
判断是否存在文件或目录name Path.exists() os.path.exists()
返回电脑的用户目录 Path.home() os.path.expanduser()
检验给出的路径是一个文件 Path.is_dir() os.path.isdir()
检验给出的路径是一个目录 Path.is_file() os.path.isfile()
检验给出的路径是一个符号链接 Path.is_symlink() os.path.islink()
获得文件属性 Path.stat() os.stat()
判断是否为绝对路径 PurePath.is_absolute() os.path.isabs()
连接目录与文件名或目录 PurePath.joinpath() os.path.join()
返回文件名 PurePath.name os.path.basename()
返回文件路径 PurePath.parent os.path.dirname()
判断两个路径是否相同 Path.samefile() os.path.samefile()
分离文件名和扩展名 PurePath.suffix os.path.splitext()

总结

本文介绍了计算机视觉项目中的文件批量操作与文件批量预处理技术。 掌握这些技术将使您能够高效地处理大规模的图像数据,并为计算机视觉项目的成功实施提供强大的支持。

希望本文对您在计算机视觉项目中的文件批量操作与文件批量预处理有所启发!

以下是完整代码文章来源地址https://www.toymoban.com/news/detail-697055.html

# -*- coding: utf-8 -*-
# @Author  : cvYouTian
# @Software: PyCharm

from pathlib import Path, PurePath
import xml.etree.ElementTree as ET
from typing import Union
import numpy as np
# import torch
from tqdm import tqdm
import time
import cv2
import os


class ExtractImg(object):
    def __init__(self, videopath: Path, savepath: Path, delay: int = 1) -> None:
        self.spath = savepath
        self.vpath = videopath
        self.delay = delay
        cv2.namedWindow("cv", cv2.WINDOW_NORMAL)
        cv2.resizeWindow("cv", 640, 480)
        self.cap = cv2.VideoCapture(str(self.vpath))
        self._timeflag = 0
        if not savepath.exists():
            os.mkdir(Path(savepath))

    def _videoPlay(self, size: list) -> None:
        self.cap.set(3, size[0])
        self.cap.set(4, size[1])
        while self.cap.isOpened():
            ret, frame = self.cap.read()
            # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            cv2.imshow("cv", frame)
            if cv2.waitKey(self.delay) & 0xFF == ord('c'):
                cv2.imwrite(str(PurePath.joinpath(self.spath,
                                                  "{}.jpg".format(str(time.time())))), frame)
                print("保存成功")
                time.sleep(1)
            elif cv2.waitKey(self.delay) & 0xFF == 27:
                break

    def ExtractAll(self, frameGap: int = 3) -> None:
        """
        这是将视频流中的帧全部抽出
        :frame: 跳帧
        :return:
        """
        while self.cap.isOpened():
            self._timeflag += 1

            ret, frame = self.cap.read()
            if ret:
                cv2.imshow("cv", frame)
                if self._timeflag % frameGap == 0:
                    cv2.imwrite(str(PurePath.joinpath(self.spath,
                                                      "{}.jpg".format(str(time.time())))), frame)
                    print("保存成功")
            if (cv2.waitKey(self.delay) & 0xFF == 27) or not ret:
                break
        cv2.destroyAllWindows()
        self.cap.release()
        self._timeflag = 0

    def CutVideo(self) -> None:
        """
        这是手动抽帧
        :return:
        """
        ifm = input("文件中已经存在{}张图片,是否有继续添加"
                    "(Y or N):".format(len(os.listdir(self.spath))))
        if self.spath.exists() and ifm == 'Y':
            self._videoPlay(size=[640, 480])
        elif self.spath.exists() and ifm == 'N':
            return None
        else:
            print("\n请输入Y(yes)或者N(no)")
        cv2.destroyAllWindows()
        self.cap.release()

    @staticmethod
    def statistics(path: Union[str, Path], dstpath: Union[Path, str], count: int = 5305, random: bool = False) -> None:
        """
        这是存放图片的文件夹安升序重命名
        :param path:需要重命名的文件文件
        :param count:观察图片总数添加使用
        """
        assert isinstance(path, (Path, str)), print("请输入的路径")
        l = os.listdir(str(path))
        if not Path.exists(dstpath):
            Path.mkdir(dstpath)
        # l = sorted(l)
        print(l)
        # print(l)
        print("存在文件{}张!".format(len(l)))
        if random:
            np.random.shuffle(l)
        # print(l)
        # 将保存图片文件中的图片按照升序的方法重命名

        suffix = Path(l[0]).suffix
        for file in tqdm(l):
            src = PurePath.joinpath(path, file)
            dst = PurePath.joinpath(dstpath, Path(str(count + int(Path(file).stem))).with_suffix(suffix))
            os.rename(src, dst)

    @staticmethod
    def choosen(src: Union[str, Path]="/home/you/Desktop/2023海上高速目标检测/val", folder: Union[Path,str]="/home/you/Desktop/2023海上高速目标检测/annotations",dst: Union[str, Path]="/home/you/Desktop/2023海上高速目标检测/train", suffix: str=".xml") -> None:
        """
        1.将xml/jpg文件夹中的文件名字拿出来并且在jpg/xml对应的文件夹中将名称相同的文件挑出来
        2.将文件夹中的文件随取出
        :param xmlsrc:目标xml文件
        :param imgsrc:frameImg文件
        :param dst:根据xml挑选出的img文件
        :return: None
        """
        # l = os.listdir(str(xmlsrc))
        if not isinstance(folder,Path):
            pa = Path(folder)
        if not isinstance(src,Path):
            l = Path(src)

        # parent = src.parent
        for i in l.iterdir():
            file = Path(i.name).with_suffix(suffix)
            (pa / file).rename(Path(dst) / file)

    @staticmethod
    def batchrenames(src: Union[str, Path], dst: Union[str, Path], sorted: bool = False) -> None:
        """
        进行特定格式的重命名
        :param src:原文件
        :param dst: 存储文件
        :param sorted: 是否已经有顺序,若有学按照1.jpg ->00001.jpg
        :return: None
        """

        d = {1: "0000",  # 这是命名格式的字典
             2: "000",
             3: "00",
             4: "0",
             5: ""}
        l = os.listdir(src)
        suffix = Path(l[0]).suffix
        l.sort(key=lambda x: int(x.split('.')[0]))
        if sorted:
            for obj in tqdm(l):
                old = PurePath.joinpath(src, obj)
                new = PurePath.joinpath(dst, d[len(obj.split('.')[0])] + obj.split('.')[0] + suffix)
                os.rename(old, new)
        else:
            # for c, i in tqdm(enumerate(l)):
            pass

    @staticmethod
    def text(file: Union[Path, str]):
        l = []
        f = open(file)
        for i in f.readlines():
            i = i.strip()
            stem = Path(i).stem
            suffix = Path(i).suffix
            n1, n2 = int(stem) - 1, int(stem) + 1
            l.append(str(n1) + ".xml")
            l.append(str(n2) + ".xml")
        print(l)

    @staticmethod
    def revampXml(xml_path: Union[Path, str], update_content: str) -> None:
        """
        这是一个修改xml文件内容的方法,将xml文件爱中的类别改称另一个类别
        :param xml_path: 存放xml文件的路径
        :param xml_dw: xpath关键字
        :param update_content: 更新的内容
        :return:None
        """
        # 打开xml文档
        if not isinstance(xml_path, Path):
            xml_path = Path(xml_path)
        for i in tqdm(xml_path.iterdir()):
            xmlfile = xml_path / f"{i}"
            doc = ET.parse(xmlfile)
            root = doc.getroot()
            # 查找修改路劲
            for obj in root.iter("object"):
                sub1 = obj.find("name")
                if sub1.text == "motorboat":
                    # 修改标签内容
                    sub1.text = update_content
                    # 保存修改
                    doc.write(xmlfile)

    @staticmethod
    def movefile(folder_path: Union[Path, str], dst: Union[Path, str], suffix: str) -> None:
        """
        批量移动剪切文件
        :param folder_path: 原文件夹路径
        :param dst: 目标文件夹路径
        :param suffix: 移动的文件格式/后缀
        :return:
        """
        if not isinstance(folder_path, Path):
            folder_path = Path(folder_path)
        # for i in folder_path.iterdir():
        #     if i.is_dir():
        #         ExtractImg.movefile(folder_path / i, suffix, res)
        #     else:
        #         if i.suffix == suffix:
        #             res.append(str(i))
        # # return res if suffix is None or suffix == "" else list(filter(lambda x: str(x).endswith(suffix),res))
        # return res
        for i in tqdm(folder_path.rglob(f"*{suffix}")):
            i.rename(dst / i.name)
    @staticmethod
    def convert_box(size, box):
            dw, dh = 1. / size[0], 1. / size[1]
            x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2]
            return x * dw, y * dh, w * dw, h * dh

  

if __name__ == "__main__":
    # 目标视频文件
    videopath = Path("videoSet/seabird6.mp4")
    # 图片保存文件
    savepath = Path("./dataset/imgs")
    # xin = Path("./VOC6detect/imgss")
    # savepath = Path("frameSave")
    # 目标xml文件
    # xmlpath = Path("./VOC6detect/annotations")
    # old = Path("/home/you/Desktop/dateset/20(pass)/seabird5")
    # new = Path("/home/you/Desktop/dateset/11(pass)/temp")
    # pa = Path("./labels/")
    # xin = Path()
    # renamepath = Path("/home/you/Desktop/dateset/4(pass)/a-1")
    # 实例化
    a = ExtractImg(videopath=videopath, savepath=savepath)
    a.choosen()
    # VOC2YOLO
    # a.convert_label()


    # 将帧全部抽出
    # a.ExtractAll(frameGap=8)

    # 手动抽帧
    # a.CutVideo()

    # 根据xml文选出对应的文件
    # a.choosen(xmlsrc=xmlpath, imgsrc=savepath, dst=xin)

    # 将数字命名的图片按照加上一个数字的方式命名
    # a.statistics(path=Path("./DATA/xml"), dstpath=Path("./DATA/t"), count=5305)

    # 对已经有顺序或者没顺序的文件进行特定格式的重命名78.jpg -> 00078.jpg
    # a.batchrenames(src=new, dst=old, sorted=True)
    # a.text("./data1.txt")
    # 对xml文件进行修改
    # a.revampXml(xml_path= "/home/you/Desktop/tools/dataset/annotations", update_content="speedboat")

    # 批量拿到文件夹中的某格式的文件
    # a.movefile(folder_path="/home/you/Desktop/网上快艇", dst=pa, suffix=".jpg")

到了这里,关于python实现视频抽帧,文件批量操作,文件批量处理(数据集制作的工具箱)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python地理数据处理 二十一:基于arcpy批量操作(三)

    实现将给定的 .shp 文件中的所有省份作为裁剪范围,对给定的 .tif 文件进行裁剪,输出所有省份的单独 .tif 文件: 实现对文件名前14个字符一样的tif图像进行栅格运算求和: 如:XXXX_XXX_2003.M01_Mean、XXXX_XXX_2003.M02_Mean、XXXX_XXX_2003.M03_Mean;XXXX_XXX_2004.M01_Mean、XXXX_XXX_2004.M02_Mean、

    2024年02月01日
    浏览(35)
  • java如何做视频抽帧,视频转图片操作Demo

    java如何做视频抽帧,视频转图片操作Demo!现在市面上很多客户提成需求,希望可以把本地的视频,抽帧(一个一个静态的图片)。至于为什么要抽帧,大家自己去百度查询。我们本次仅仅讨论如何使用java技术,实现视频的抽帧操作。 1:我们需要用到市面上一个的maven插件包。名

    2024年04月09日
    浏览(24)
  • javacv处理rtsp流,抽帧,转hls流,播放视频

    整体项目结构: pom文件引入依赖: 1.播放视频 video类: 效果展示:   2.转换hls流 效果展示   3.抽帧 效果: 工具类代码:  

    2024年02月13日
    浏览(34)
  • 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频

    目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割得到的视频存放在新建文件夹下(这个我运行的时候好像有点问题,音频文件没有存放在新建

    2023年04月08日
    浏览(45)
  • 视频抽帧实现

    一、基本概念理解 一个视频由视频帧构成,每一帧在肉眼可见是一张图片成像 1、视频帧 帧的类型: 帧的类型主要参考 视频抽帧处理 I帧,Intra Picture,内编码帧,也就是关键帧。拥有完整的图像信息。I帧不需要依赖前后帧信息,可独立进行解码。 P帧,predictive-frame,前向预

    2024年02月16日
    浏览(25)
  • PyQt实现视频抽帧显示

    PyQt实现视频抽帧显示 导入必要的库。 创建一个QTimer对象,用于循环读取视频帧并进行抽帧。 定义show_frame函数,该函数将读取视频帧并将其显示在PyQt窗口中。

    2024年02月07日
    浏览(24)
  • java实现视频抽帧以及获取其他视频信息

    1.在pom.xml文件中导入jar包 2.创建工具类FetchVideoFrameUtil,复制以下代码 文章引用出处:https://cloud.tencent.com/developer/article/1655887,并在原有基础上做了优化

    2024年02月12日
    浏览(29)
  • Python文件操作和异常处理:高效处理数据的利器

    重温Python,适合新手搭建知识体系,也适合大佬的温故知新~ 1.1 文件操作和异常处理对于编程的重要性 文件操作和异常处理对于编程非常重要。它们使得我们能够处理文件数据、持久化数据、导入和导出数据,并且能够优雅地处理和解决错误,提高程序的可靠性和稳定性。

    2024年01月23日
    浏览(39)
  • 【Python入门教程】基于OpenCV视频分解成图片+图片组合成视频(视频抽帧组帧)

            在人工智能爆火的今天,深度学习被广泛应用于各个领域。深度学习的模型训练离不开大量的样本库。我之前分享过【Python爬虫】批量爬取网页的图片制作数据集,今天跟大家分享一下如何使用OpenCV库对视频进行抽帧,从而增加样本图片的数量。正好也顺便分享一下

    2024年02月04日
    浏览(28)
  • Vue 3 + ffmpeg + wasm 实现前端视频剪辑、音频剪辑、音波展示、视频抽帧、gif抽帧、帧播放器、字幕、贴图、时间轴、素材轨道

    预览 www.bilibili.com/video/BV1YT411Y7YJ 技术栈: 💪 Vue 3、Vue-Router 4、Vite、pnpm、esbuild、TypeScript ☀️ Pinia 状态管理 🌪 Tailwind 原子css集成 💥 ffmpeg、wasm 底层音视频处理集成 功能 多轨道时间轴,支持帧缩放,时间缩放 支持多种类型轨道的添加删除 多功能轨道调节,支持音视频轨

    2024年02月11日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包