目标检测学习笔记(二)——图片取样及数据集制作

2024-02-07 04:08

本文主要是介绍目标检测学习笔记(二)——图片取样及数据集制作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 拍摄视频并提取图片
    • 拍摄视频
    • 提取图片
      • 方法1:视频帧差法提取图片
      • 方法2:定时从视频截图
    • 整理文件并重命名
  • 数据集制作
      • labelimg的安装及使用
      • 批量修改标签名称

前言

参考:

从视频中提取图片:如何将视频逐帧提取成为一张张图片?

图片重命名:python文件批量改名

制作数据集:睿智的目标检测12——使用labeling进行目标检测数据集标注

批量修改标签名称:如何批量修改Pascal VOC数据集中xml标签中的标签名称

拍摄视频并提取图片

拍摄视频

getvedio.py

'''
python 录制mp4视频 by 郑瑞国
'''
import numpy as np
import cv2cap = cv2.VideoCapture(0)## some videowriter props
sz = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))fps = 20
# fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
# fourcc = cv2.VideoWriter_fourcc('m', 'p', 'e', 'g')
fourcc = cv2.VideoWriter_fourcc(*'mpeg')## open and set props
out = cv2.VideoWriter()
out.open('getvedio/16.mp4', fourcc, fps, sz, True)while (True):ret, frame = cap.read()out.write(frame)cv2.imshow('frame', frame)if cv2.waitKey(1) & 0xff == ord('q'):breakout.release()
cap.release()
cv2.destroyAllWindows()

提取图片

方法1:视频帧差法提取图片

frame_extract.py

# -*- coding: utf-8 -*-import cv2
import numpy as np
import os
import urllibdef frame_difference(frame1, frame2):   #求取侦差# f1, f2 f1 = cv2.resize(frame1, (416, 416))f2 = cv2.resize(frame2, (416, 416))f1 = cv2.cvtColor(f1, cv2.COLOR_BGR2GRAY)f2 = cv2.cvtColor(f2, cv2.COLOR_BGR2GRAY)                 # 灰度化f1 = cv2.threshold(f1, 128, 255, cv2.THRESH_BINARY)[1]    # 二值化f2 = cv2.threshold(f2, 128, 255, cv2.THRESH_BINARY)[1]diff = cv2.absdiff(f1, f2)          #求取差值p = cv2.countNonZero(diff) / float(416 * 416)return pif __name__ == "__main__":root = r'F:\0-0\Myyolo\vedio_img\getvedio'threshold = 0.09      #阙值frame_interval = 15    #帧间隔save_root = r'F:\0-0\Myyolo\vedio_img\getvedio\img'for c, path in enumerate(os.listdir(root)):path = os.path.join(root, path)video = cv2.VideoCapture(path)count = 0st, frame1 = video.read() #st,frame是获cv2.VideoCapture.read()方法的两个返回值。st, frame2 = video.read() #其中st是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵。while st:if count % frame_interval == 0:st, frame2 = video.read()p = frame_difference(frame1, frame2)  #求取侦差print(p)if p > threshold:save_dir = os.path.join(save_root, os.path.splitext(os.path.basename(path))[0])if not os.path.exists(save_dir):                                        #如果目录不存在os.makedirs(save_dir)   #创建目录print(save_dir)#cv2.imencode(os.path.join(save_dir, str(count)+'.jpg'), frame1)#cv2.imencode(str(count)+'.jpg', frame1)[1].tofile(save_dir)cv2.imwrite(os.path.join(save_dir, str(count) + '.jpg'), frame1)print('保存图片')frame1 = frame2st, frame2 = video.read()count += 1if st:cv2.imshow("video%d"%c, frame2)  #函数可以在窗口中显示图像。该窗口和图像的原始大小自适应(自动调整到原始尺寸)。cv2.waitKey(100)   #是一个和键盘绑定的函数,它的作用是等待一个键盘的输入(因为我们创建的图片窗口如果没有这个函数的话会闪一下就消失了,所以如果需要让它持久输出,我们可以使用该函数)。它的参数是毫秒级。该函数等待任何键盘事件的指定毫秒。如果您在此期间按下任何键,程序将继续进行。我们也可以将其设置为一个特定的键。video.release()           #发布软件资源  /  释放硬件资源cv2.destroyAllWindows()   #销毁我们创建的所有窗口。如果要销毁任何特定窗口,请使用函数cv2.destroyWindow(),其中传递确切的窗口名称作为参数。(应该是使用创建窗口时所使用的窗口名称,字符串类型。)print("video%d"%c, "done!")

方法2:定时从视频截图

使用img_extract.py

# 每隔 多少 秒 提取视频中的图片到文件夹# This is a sample Python script.# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.def print_hi(name):# Use a breakpoint in the code line below to debug your script.print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.# Press the green button in the gutter to run the script.
if __name__ == '__main__':print_hi('PyCharm')# See PyCharm help at https://www.jetbrains.com/help/pycharm/
# -*- coding: utf-8 -*-
import os
import cv2    ##加载OpenCV模块def video2frames(pathIn: object = '',pathOut: object = '',only_output_video_info: object = False,extract_time_points: object = None,initial_extract_time: object = 0,end_extract_time: object = None,extract_time_interval: object = -1,output_prefix: object = 'frame',jpg_quality: object = 100,isColor: object = True) -> object:'''pathIn:视频的路径,比如:F:\python_tutorials\test.mp4pathOut:设定提取的图片保存在哪个文件夹下,比如:F:\python_tutorials\frames1\。如果该文件夹不存在,函数将自动创建它only_output_video_info:如果为True,只输出视频信息(长度、帧数和帧率),不提取图片extract_time_points:提取的时间点,单位为秒,为元组数据,比如,(2, 3, 5)表示只提取视频第2秒, 第3秒,第5秒图片initial_extract_time:提取的起始时刻,单位为秒,默认为0(即从视频最开始提取)end_extract_time:提取的终止时刻,单位为秒,默认为None(即视频终点)extract_time_interval:提取的时间间隔,单位为秒,默认为-1(即输出时间范围内的所有帧)output_prefix:图片的前缀名,默认为frame,图片的名称将为frame_000001.jpg、frame_000002.jpg、frame_000003.jpg......jpg_quality:设置图片质量,范围为0到100,默认为100(质量最佳)isColor:如果为False,输出的将是黑白图片'''cap = cv2.VideoCapture(pathIn)  ##打开视频文件n_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))  ##视频的帧数fps = cap.get(cv2.CAP_PROP_FPS)  ##视频的帧率dur = n_frames/fps  ##视频的时间##如果only_output_video_info=True, 只输出视频信息,不提取图片if only_output_video_info:print('only output the video information (without extract frames)::::::')print("Duration of the video: {} seconds".format(dur))print("Number of frames: {}".format(n_frames))print("Frames per second (FPS): {}".format(fps))##提取特定时间点图片elif extract_time_points is not None:if max(extract_time_points) > dur:   ##判断时间点是否符合要求raise NameError('the max time point is larger than the video duration....')try:os.mkdir(pathOut)except OSError:passsuccess = Truecount = 0while success and count < len(extract_time_points):cap.set(cv2.CAP_PROP_POS_MSEC, (1000*extract_time_points[count]))success,image = cap.read()if success:if not isColor:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  ##转化为黑白图片print('Write a new frame: {}, {}th'.format(success, count+1))cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG filecount = count + 1else:##判断起始时间、终止时间参数是否符合要求if initial_extract_time > dur:raise NameError('initial extract time is larger than the video duration....')if end_extract_time is not None:if end_extract_time > dur:raise NameError('end extract time is larger than the video duration....')if initial_extract_time > end_extract_time:raise NameError('end extract time is less than the initial extract time....')##时间范围内的每帧图片都输出if extract_time_interval == -1:if initial_extract_time > 0:cap.set(cv2.CAP_PROP_POS_MSEC, (1000*initial_extract_time))try:os.mkdir(pathOut)except OSError:passprint('Converting a video into frames......')if end_extract_time is not None:N = (end_extract_time - initial_extract_time)*fps + 1success = Truecount = 0while success and count < N:success,image = cap.read()if success:if not isColor:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)print('Write a new frame: {}, {}/{}'.format(success, count+1, n_frames))cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG filecount =  count + 1else:success = Truecount = 0while success:success,image = cap.read()if success:if not isColor:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)print('Write a new frame: {}, {}/{}'.format(success, count+1, n_frames))cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG filecount =  count + 1##判断提取时间间隔设置是否符合要求elif extract_time_interval > 0 and extract_time_interval < 1/fps:raise NameError('extract_time_interval is less than the frame time interval....')elif extract_time_interval > (n_frames/fps):raise NameError('extract_time_interval is larger than the duration of the video....')##时间范围内每隔一段时间输出一张图片else:try:os.mkdir(pathOut)except OSError:passprint('Converting a video into frames......')if end_extract_time is not None:N = (end_extract_time - initial_extract_time)/extract_time_interval + 1success = Truecount = 0while success and count < N:cap.set(cv2.CAP_PROP_POS_MSEC, (1000*initial_extract_time+count*1000*extract_time_interval))success,image = cap.read()if success:if not isColor:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)print('Write a new frame: {}, {}th'.format(success, count+1))cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG filecount = count + 1else:success = Truecount = 0while success:cap.set(cv2.CAP_PROP_POS_MSEC, (1000*initial_extract_time+count*1000*extract_time_interval))success,image = cap.read()if success:if not isColor:image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)print('Write a new frame: {}, {}th'.format(success, count+1))cv2.imwrite(os.path.join(pathOut, "{}_{:06d}.jpg".format(output_prefix, count+1)), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])     # save frame as JPEG filecount = count + 1##### 测试
# pathIn = 'pathIn/1.1.avi'# video2frames(pathIn, only_output_video_info = True) #只输出视频信息(长度、帧数和帧率),不提取图片
#
# pathOut = './frames1/'
# video2frames(pathIn, pathOut)
#
# pathOut = './frames2'
# video2frames(pathIn, pathOut, extract_time_points=(1, 2, 5)) #提取的时间点,单位为秒,为元组数据,比如,(2, 3, 5)表示只提取视频第2秒, 第3秒,第5秒图片
#
# pathOut = './frames3'
# video2frames(pathIn, pathOut,
#              initial_extract_time=1,          #提取的起始时刻,单位为秒,默认为0(即从视频最开始提取)
#              end_extract_time=3,              #提取的终止时刻,单位为秒,默认为None(即视频终点)
#              extract_time_interval = 0.5)     #提取的时间间隔,单位为秒,默认为-1(即输出时间范围内的所有帧)
#
# pathOut = './frames4/'
# video2frames(pathIn, pathOut, extract_time_points=(0.3, 2), isColor = False)  #isColor:如果为False,输出的将是黑白图片
#
#
# pathOut = './frames5/'
# video2frames(pathIn, pathOut, extract_time_points=(0.3, 2), jpg_quality=50)   #jpg_quality:设置图片质量,范围为0到100,默认为100(质量最佳)#输出
# pathIn = 'pathIn/1.1.avi'
pathIn = '0'
pathOut = 'pathOut/1/'
video2frames(pathIn, pathOut, extract_time_interval = 5, jpg_quality=100)

整理文件并重命名

先设置文件夹名称,再用img_rename.py

import os#将多个文件夹文件调到一个文件里面,并重命名
m = 0   # 文件夹名称
#for i in range(1,15):   #对14个文件夹中的 图片 调用到一个文件夹中
for i in range(1,2):m = 15m += 1# 输入路径# path = input('请输入文件路径(结尾加上/):')path = 'getvedio/img/' + str(m) + '/'# 输出路径path2 = 'getvedio/img_rename/'# 获取该目录下所有文件,存入列表中f = os.listdir(path)#重命名n = 1for i in f:# 设置旧文件名(就是路径+文件名)oldname = path + f[n - 1]# 设置新文件名newname = path2 +str(m) + '_' + str(n) + '.JPG'# 用os模块中的rename方法对文件改名os.renames(oldname, newname)print(oldname, '======>', newname)n += 1# #
# m = 1
# n = 1
# #输入路径
# # path = input('请输入文件路径(结尾加上/):')
# path = 'img_pre/' + str(m) + '/'
# #输出路径
# path2 = 'img_ed/'
# # 获取该目录下所有文件,存入列表中
# f = os.listdir(path)
#
# for i in f:
#     # 设置旧文件名(就是路径+文件名)
#     oldname = path + f[n - 1]
#
#     # 设置新文件名
#     newname = path2  + str(n) + '.JPG'
#
#     # 用os模块中的rename方法对文件改名
#     os.renames(oldname, newname)
#     print(oldname, '======>', newname)
#     n += 1

数据集制作

labelimg的安装及使用

  • 安装及启动

安装:

pip install labelimg

启动命令:

labelimg
  • 标记图片

image-20201103191218092

JPEGimages储存原图片

数据集(.xml文件 )保存至 Annotations

然后 复制到 VOCdevkit/VOC2007 文件夹中。

批量修改标签名称

参考:如何批量修改Pascal VOC数据集中xml标签中的标签名称

运行xml_rename.py

import os
import xml.etree.ElementTree as ET#程序功能:批量修改VOC数据集中xml标签文件的标签名称
def changelabelname(inputpath):listdir = os.listdir(inputpath)for file in listdir:if file.endswith('xml'):file = os.path.join(inputpath,file)tree = ET.parse(file)root = tree.getroot()for object1 in root.findall('object'):for sku in object1.findall('name'):           #查找需要修改的名称if (sku.text == 'preName'):               #‘preName’为修改前的名称sku.text = 'TESTNAME'                 #‘TESTNAME’为修改后的名称tree.write(file,encoding='utf-8')     #写进原始的xml文件并避免原始xml中文字符乱码else:passelse:passif __name__ == '__main__':inputpath = 'E:/Research/Dataset/Test/Annotations'  #此处替换为自己的路径changelabelname(inputpath)

这篇关于目标检测学习笔记(二)——图片取样及数据集制作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/686473

相关文章

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过