用ImageAI将普通视频转换为带目标检测的视频

本文介绍如何利用ImageAI开源项目将普通视频转换为带有目标检测效果的视频,包括人形和物品检测。详细步骤涉及环境搭建、依赖安装、模型选择及视频处理代码示例。

之前我发表过一篇博客,是使用opencv将普通视频转为带人脸检测效果的视频

https://blog.youkuaiyun.com/luohualiushui1/article/details/86661501

现在选用一个开源项目ImageAI将普通视频转换为带目标检测的视频,目标检测包括人形检测和一些普通的物品检测。也就是说,我们会把一个普通的视频转换为一个里面的人形和物品画上框加上标注的视频。

首先大家了解一下ImageAI开源项目https://github.com/OlafenwaMoses/ImageAI

它的说明文档https://imageai-cn.readthedocs.io/zh_CN/latest/ImageAI_Object_Detection.html

该开源项目基于tensorflow,它里面使用了好几种目标检测的模型都是源于tensorflow提供的训练模型。

例如:RetinaNet, YOLOv3 和 TinyYOLOv3

现在开始正题

第一步在ubuntu上搭建相关环境,按照ImageAI项目的指引,给python安装依赖,如下:

pip3 install --upgrade tensorflow 
pip3 install numpy 
pip3 install scipy 
pip3 install opencv-python 
pip3 install pillow 
pip3 install matplotlib 
pip3 install h5py 
pip3 install keras 

第二步安装ImageAI

pip3 install https://github.com/OlafenwaMoses/ImageAI/releases/download/2.0.2/imageai-2.0.2-py3-none-any.whl

第三步在PyCharm上新建工程引入ImageAI。

第四步ImageAI对视频处理封装的比较好,只需要如下处理即可:

from imageai.Detection import VideoObjectDetection
import os

execution_path = os.getcwd()

detector = VideoObjectDetection()
detector.setModelTypeAsRetinaNet()
detector.setModelPath( os.path.join(execution_path, "resnet50_coco_best_v2.0.1.h5"))
detector.loadModel()

video_path = detector.detectObjectsFromVideo(input_file_path="/usr/local/video/229728.mp4", output_file_path="/usr/local/video/229728_p", frames_per_second=20, log_progress=True)
print(video_path)

运行起来相当花时间,资源消耗也不低,在长时间的运行之后才输出处理后的视频

效果如下图:

ok生成完毕,但是大家可以发现检测效果还好,但生成的视频色泽相当于原视频发生了变化,人脸部偏蓝。

<think>我们正在讨论如何使用ArcGISPro进行标注并将标注数据导入YOLO目标检测模型。根据之前的引用[2],用户可能已经了解了一些ArcGISPro的栅格数据处理操作,但现在的需求是标注(这里通常指目标检测的标注)并用于YOLO。步骤概述:1.在ArcGISPro中准备影像数据,并进行标注(如绘制多边形、矩形等)。2.导出标注数据为YOLO所需的格式(通常是每个图像对应一个txt文件,包含类别索引和归一化的边界框坐标)。3.准备YOLO的训练环境(例如Darknet或YOLOv5等),并调整配置文件。4.将标注数据和图像数据导入到YOLO中进行训练。由于YOLO需要的是边界框坐标(通常是中心点坐标、宽度和高度,并且归一化到0-1之间),而ArcGISPro默认的标注格式(如shapefile)需要转换。详细步骤:###步骤1:在ArcGISPro中标注数据-打开ArcGISPro,加载你的影像数据(例如栅格图像)。-创建新的要素类(FeatureClass)用于存储标注。在创建时,设置几何类型为“面”(用于矩形框或多边形)或“折线”(如果画线状目标)。但注意,目标检测通常用矩形框,所以建议用“面”,然后画矩形框。-在要素类属性表中,添加一个字段来存储类别名称(如“class_name”)。-使用编辑工具,在影像上绘制每个目标的边界框(矩形)。绘制时,确保每个矩形框对应一个目标,并填写类别名称。注意:如果目标数量多,可以使用批量标注工具(如AI赋能的标注工具),但这里我们讨论手动标注。###步骤2:将标注转换为YOLO格式-导出标注要素类为shapefile或地理数据库要素类(如果已经在地理数据库中)。-由于YOLO的标注格式是每个图像一个txt文件,每行一个目标,格式为:`<class_id><center_x><center_y><width><height>`,其中坐标是归一化的(相对于图像宽度和高度)。-我们需要将每个矩形框(即每个面要素)转换为这个格式。转换步骤:a.获取每个标注矩形框的边界(xmin,ymin,xmax,ymax)以及图像对应的宽度(img_width)和高度(img_height)。b.计算归一化后的中心点坐标和宽高:center_x=(xmin+xmax)/(2.0*img_width)center_y=(ymin+ymax)/(2.0*img_height)width=(xmax-xmin)/img_widthheight=(ymax-ymin)/img_heightc.将每个目标的类别名称映射为一个整数索引(如0,1,2,...),并写入txt文件。注意:ArcGISPro中,我们可以使用字段计算器或者编写一个Python脚本来实现转换。但是ArcGISPro本身没有直接支持YOLO格式的导出工具,因此需要自定义转换。建议使用ArcGISPro的Python窗口或者创建Python工具箱,利用ArcPy模块来处理。示例脚本(在ArcGISPro的Python窗口中运行)的大致步骤:1.读取要素类(包含标注矩形框)和对应的影像。2.获取影像的宽度和高度(可以使用`arcpy.Raster`类来读取影像属性)。3.遍历每个要素,计算其归一化后的坐标。4.为每个影像创建txt文件(文件名与影像文件名一致),将属于该影像的所有标注写入。注意:在要素类中,需要有一个字段记录该矩形框属于哪张影像(如果多张影像在一个要素类中,则需要用关联字段)。如果每张影像单独一个要素类,则不需要。###步骤3:准备YOLO训练数据-将影像和对应的txt标注文件组织成以下目录结构(以YOLOv5为例):dataset/images/train/val/labels/train/val/-注意:每个图像在labels目录中有一个同名的txt文件。###步骤4:在YOLO中训练-下载YOLO框架(例如YOLOv5:https://github.com/ultralytics/yolov5)-创建数据集配置文件(如`data.yaml`),指定类别名称和目录路径。-运行训练命令,例如:pythontrain.py--img640--batch16--epochs50--datadata.yaml--weightsyolov5s.pt注意:在转换坐标时,注意ArcGISPro中影像的坐标系统(特别是地理坐标系统)可能会影响坐标值。如果影像已经投影到平面坐标,那么直接使用平面坐标计算;如果影像没有地理参考,则可能是以像素为单位的点(此时左上角为原点(0,0),向右为x正,向下为y正)。在标注时,如果使用地理参考影像,绘制矩形框使用的是地图坐标(可能是米等),这需要特别注意。因此,建议使用未地理参考的影像(即像素坐标)进行标注,或者将影像转换为像素坐标系统(例如使用栅格处理工具重置坐标系?),否则计算归一化坐标会复杂得多。更简单的方法:在标注前,确保影像的坐标系被设置为投影坐标系(单位是米)或未知坐标系(像素坐标)。如果使用地理坐标系(度),则边界框可能会因为变形而不准确。如果确实需要处理地理参考的影像,需要先将影像的坐标转换为像素坐标,即计算每个像素在地图上的实际位置,然后根据实际位置计算归一化坐标?但通常目标检测不需要地图坐标,只需要图像上的像素位置。因此,推荐使用未地理参考的影像(没有坐标系统),或者使用栅格数据集,其坐标系统设置为像素坐标(例如使用栅格处理工具创建金字塔时,以像素为单位)。如果影像有地理参考,你可能需要将其重投影到一个以米为单位的坐标系,然后使用地理处理工具提取出每个影像块对应的实际坐标范围。这比较复杂。替代方案:使用非地理参考的影像进行标注(例如先将影像导出为无地理参考的图片格式,如jpg/png,然后在ArcGISPro中加载这些图片,这样绘制时的单位就是像素)。这样在导出标注时,就可以直接使用像素坐标了。具体做法:-在ArcGISPro中,如果你有地理参考的影像,你可以先将其导出为图片(但这样会丢失地理参考?)。或者,在绘制矩形框时,使用“相对路径”方式加载影像,这样ArcGISPro会将影像显示为普通图片(像素坐标)。在ArcGISPro中,如果你加载的是栅格数据,并且它的坐标系是地理坐标系(如WGS84),那么你绘制的矩形框将使用经纬度。这样在转换为像素坐标时,需要知道每个影像对应地理范围以及影像的像素尺寸(列数和行数),然后进行转换。这需要额外的步骤。因此,为了简化,我们假设使用无地理参考的影像(或者已经将地理参考影像裁剪成小块,并且我们只使用像素位置)。这样,在标注时,我们就可以直接使用像素位置。总结:建议将大影像裁剪成小图块(例如640x640),然后对每个图块进行标注。这样,在计算归一化坐标时,直接使用像素坐标除以图块尺寸即可。###代码示例(使用ArcPy将要素类标注转换为YOLO格式)假设我们有一个要素类,其中包含以下字段:image_name:影像文件名(不含扩展名,用于匹配图像和标注)class_name:类别名称xmin,ymin,xmax,ymax:矩形框的像素坐标(注意:这里的坐标是像素坐标,原点在左上角)注意:我们在要素类中可能没有直接存储xmin,ymin等,而是存储了多边形。因此,我们需要从几何字段中提取矩形框的边界。以下是一个示例脚本:```pythonimportarcpyimportos#设置要素类路径和影像目录feature_class=r"path_to_your_feature_class"image_dir=r"path_to_directory_containing_images"output_label_dir=r"path_to_output_labels"#确保输出目录存在os.makedirs(output_label_dir,exist_ok=True)#获取要素类的字段:需要包含影像文件名(用于匹配)和类别名称#假设字段名为:"image","class_name"fields=["image","class_name","SHAPE@"]class_map={}#将类别名称映射为整数索引classes=[]#第一步:收集所有类别witharcpy.da.SearchCursor(feature_class,["class_name"])ascursor:forrowincursor:class_name=row[0]ifclass_namenotinclass_map:class_map[class_name]=len(classes)classes.append(class_name)print(f"Classes:{classes}")#第二步:为每个影像创建标注文件witharcpy.da.SearchCursor(feature_class,fields)ascursor:forrowincursor:image_name=row[0]#如'image001'class_name=row[1]geometry=row[2]#面要素#获取矩形的范围extent=geometry.extentxmin=extent.XMinymin=extent.YMinxmax=extent.XMaxymax=extent.YMax#现在我们需要知道对应影像的尺寸(宽高)#假设影像文件在image_dir下,扩展名可能是tif,jpg等#我们尝试在目录中寻找与image_name匹配的影像#注意:这里需要根据实际文件名调整,比如image_name可能是扩展名或不matching_files=[fforfinos.listdir(image_dir)iff.startswith(image_name)]ifnotmatching_files:print(f"Warning:Noimagefoundfor{image_name}in{image_dir}")continue#这里假设第一个匹配的文件就是img_file=matching_files[0]#读取影像尺寸(使用arcpy.Raster)raster=arcpy.Raster(os.path.join(image_dir,img_file))width=raster.widthheight=raster.height#计算归一化坐标center_x=(xmin+xmax)/(2*width)center_y=(ymin+ymax)/(2*height)w=(xmax-xmin)/widthh=(ymax-ymin)/height#写入到对应的标注文件(txt)#标注文件名:与影像文件名相同,但扩展名为txt(放在输出目录)label_file=os.path.join(output_label_dir,f"{image_name}.txt")withopen(label_file,'a')asf:line=f"{class_map[class_name]}{center_x:.6f}{center_y:.6f}{w:.6f}{h:.6f}\n"f.write(line)#清除raster对象delrasterprint("Conversioncomplete.")```注意:这个脚本假设每个影像只被遍历一次,但实际上一个影像可能有多个目标,所以每个目标都会被写入同一个txt文件。因此,我们使用追加模式('a')打开文件。同时,在创建txt文件时,如果已存在则追加,不存在则创建。问题:该脚本可能会多次打开同一个文件(因为一个影像有多个目标)。这是合理的。重要:这个脚本只是示例,实际中需要根据你的要素类结构和数据调整。特别是要素类中的字段名和影像的存储方式。###步骤5:在YOLO中训练-将得到的labels目录和images目录按照YOLO要求放置。-创建`data.yaml`文件,内容示例:train:../images/trainval:../images/valnames:0:class01:class1...-然后就可以开始训练了。总结:整个流程的关键在于将ArcGISPro的标注转换为YOLO格式。这需要编程步骤,但可以借助ArcGISPro的Python环境和ArcPy模块实现。相关问题:1.如何在不使用ArcPy的情况下进行标注转换?2.如果我的影像有地理参考,如何准确计算像素坐标?3.有没有更简单的方法直接在ArcGISPro中导出YOLO格式?4.如何提高在ArcGISPro中的标注效率?</think> ### 使用ArcGIS Pro标注数据并导入YOLO目标检测模型的步骤 #### 一、ArcGIS Pro数据标注流程 1. **创建标注工程** - 在ArcGIS Pro中新建地图工程 → 加载待标注影像数据(如栅格图片) - 在**目录窗格**右键 → 新建 → **Shapefile**(选择面要素类型) - 添加分类字段(如`class_name`文本字段)存储目标类别[^2] 2. **执行标注** ```python # ArcPy标注示例伪代码 with arcpy.da.InsertCursor("标注图层", ["SHAPE@", "class_name"]) as cursor: while 标注未完成: # 手动绘制目标边界框(矩形) polygon = 鼠标绘制的矩形面 cursor.insertRow([polygon, "目标类别"]) ``` - 使用**编辑工具**手动绘制目标边界框(建议关闭地图地理坐标参考,使用像素坐标系) 3. **数据导出** - 要素类转CSV: ```python arcpy.ExportXYv_stats("标注图层", ["class_name"], "COMMA", "标注坐标.csv") ``` - 同时导出原始影像为JPEG/PNG格式(保持与标注同名) #### 二、标注数据转换YOLO格式 YOLO要求格式(每张图片对应.txt文件): ``` <类别ID> <中心点X百分比> <中心点Y百分比> <宽度百分比> <高度百分比> ``` 转换步骤: 1. **计算归一化坐标** ```python # 转换脚本示例 with open("标注坐标.csv") as f, open(img_name + ".txt", "w") as out: for row in csv.reader(f): x_min, y_min, x_max, y_max = 从几何字段解析坐标 img_w, img_h = 图片尺寸 center_x = ((x_min + x_max)/2) / img_w # 中心点X百分比 center_y = ((y_min + y_max)/2) / img_h # 中心点Y百分比 width = (x_max - x_min) / img_w # 宽度百分比 height = (y_max - y_min) / img_h # 高度百分比 out.write(f"{class_id} {center_x:.6f} {center_y:.6f} {width:.6f} {height:.6f}\n") ``` 2. **目录结构组织** ``` dataset/ ├─ images/ │ ├─ train/ # 训练图片 │ └─ val/ # 验证图片 └─ labels/ ├─ train/ # 训练标注 └─ val/ # 验证标注 ``` #### 三、YOLO模型训练部署 1. **安装YOLO环境**(以YOLOv5为例): ```bash git clone https://github.com/ultralytics/yolov5 pip install -r yolov5/requirements.txt ``` 2. **创建YAML配置文件**(`data.yaml`): ```yaml train: ../dataset/images/train val: ../dataset/images/val names: 0: 类别A 1: 类别B ``` 3. **启动训练**: ```bash python train.py --img 640 --batch 16 --epochs 50 --data data.yaml --weights yolov5s.pt ``` #### 注意事项 1. 标注精度影响:确保边界框紧密贴合目标边缘 2. 坐标归一化:转换时需用原始图片尺寸(宽高)计算百分比 3. 类别一致性:标注时的类别名称需与训练配置文件`names`完全匹配 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边草随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值