【YOLO系列】YOLOv3代码详解(五):utils.py脚本

前言

        以下内容仅为个人在学习人工智能中所记录的笔记,先将目标识别算法yolo系列的整理出来分享给大家,供大家学习参考。

        本文仅对YOLOV3代码中关键部分进行了注释,未掌握基础代码的铁汁可以自己百度一下。

        若文中内容有误,希望大家批评指正。


资料下载

        YOLOV3论文下载地址:YOLOv3:An Incremental Improvement

回顾

        YOLO V1:【YOLO系列】YOLO V1论文思想详解

        YOLO V2:【YOLO系列】YOLO V2论文思想详解

        YOLO V3:【YOLO系列】 YOLOv3论文思想详解

项目地址

        YOLOV3 keras版本:下载地址

        YOLOV3 Tensorflow版本:下载地址

        YOLOV3 Pytorch版本:下载地址

Gitee仓库

        YOLOV3 各版本:yolov3各版本


YOLO V3代码详解

        YOLO V3代码详解(一):【YOLO系列】YOLOv3代码详解(一):主脚本yolo_video.py

        YOLO V3代码详解(二):【YOLO系列】YOLOv3代码详解(二):检测脚本yolo.py

        YOLO V3代码详解(三):【YOLO系列】YOLOv3代码详解(三):训练脚本train.py

        YOLO V3代码详解(四):【YOLO系列】YOLOv3代码详解(四):模型脚本model.py


        本文主要基于keras版本进行讲解

        话不多说,直接上代码


一、代码详解

1、定义递归操作函数

        将funcs中的元素进行某种累积或合并

def compose(*funcs):"""Compose arbitrarily many functions, evaluated left to right.Reference: https://mathieularose.com/function-composition-in-python/"""# return lambda x: reduce(lambda v, f: f(v), funcs, x)# 递归操作,将funcs中的元素进行某种累积或合并if funcs:return reduce(lambda f, g: lambda *a, **kw: g(f(*a, **kw)), funcs)else:raise ValueError('Composition of empty sequence not supported.')

2、输入图片的尺寸处理

        (1)将输入的图片按最长边确定一个比例,然后按比例缩放(采样方法:BICUBIC)图片;

        (2) 再生成一个用“绝对灰”R128-G128-B128填充的416x416新图片后将缩放后的输入图片粘贴上去,粘贴不到的部分保留为灰色。

def letterbox_image(image, size):"""resize image with unchanged aspect ratio using padding"""# 将输入的图片按最长边确定一个比例,然后按比例缩放(采样方法:BICUBIC)图片# 再生成一个用“绝对灰”R128-G128-B128填充的416x416新图片后将缩放后的输入图片粘贴上去,粘贴不到的部分保留为灰色iw, ih = image.sizew, h = size# 选择一个最长边作为缩放比例scale = min(w/iw, h/ih)nw = int(iw*scale)nh = int(ih*scale)image = image.resize((nw, nh), Image.BICUBIC)new_image = Image.new('RGB', size, (128, 128, 128))new_image.paste(image, ((w-nw)//2, (h-nh)//2))return new_image

3、定义get_random_data()函数

        实现图片数据增强

def rand(a=0, b=1):# 获得范围为[a,b]的随机数return np.random.rand()*(b-a) + adef get_random_data(annotation_line, input_shape, random=True, max_boxes=20, jitter=.3, hue=.1, sat=1.5, val=1.5, proc_img=True):"""random preprocessing for real-time data augmentation通过随机缩放的方式调整图片的尺寸至(416, 416),随机改变图片的RGB、翻转方式来实现图片数据增强"""line = annotation_line.split()image = Image.open(line[0])   # 打开需要训练的图片iw, ih = image.size     # 获取图片的宽度与高度h, w = input_shape     # (416, 416)# 获取Gound Truth框box = np.array([np.array(list(map(int, box.split(',')))) for box in line[1:]])if not random:# 这里是将输入的图片大小调整为(416, 416),方法与yolo.py中提到的一致scale = min(w/iw, h/ih)nw = int(iw*scale)nh = int(ih*scale)dx = (w-nw)//2dy = (h-nh)//2image_data = 0if proc_img:image = image.resize((nw, nh), Image.BICUBIC)new_image = Image.new('RGB', (w, h), (128, 128, 128))new_image.paste(image, (dx, dy))image_data = np.array(new_image)/255.# correct boxes# 图片大小被改变后,Gound Truth框也需要调整box_data = np.zeros((max_boxes, 5))if len(box) > 0:np.random.shuffle(box)if len(box) > max_boxes: box = box[:max_boxes]box[:, [0, 2]] = box[:, [0, 2]]*scale + dxbox[:, [1, 3]] = box[:, [1, 3]]*scale + dybox_data[:len(box)] = boxreturn image_data, box_data# resize image# 随机得到一个新的比例,来缩放图片的尺寸# new_ar= w/h * rand(0.7, 1.3)/rand(0.7, 1.3),rand(0.7, 1.3)=np.random.rand()*(1.3-0.7) + 0.7=[0.7,1.3]# new_ar>1说明w>h,new_ar<1说明w<hnew_ar = w/h * rand(1-jitter, 1+jitter)/rand(1-jitter, 1+jitter)scale = rand(.25, 2)if new_ar < 1:nh = int(scale*h)nw = int(nh*new_ar)else:nw = int(scale*w)nh = int(nw/new_ar)image = image.resize((nw, nh), Image.BICUBIC)# place image# 生成一个灰度的(416, 416)图片,再将缩放后的输入图片粘贴到这个灰色图片上,粘贴位置随机生成dx = int(rand(0, w-nw))dy = int(rand(0, h-nh))new_image = Image.new('RGB', (w, h), (128, 128, 128))new_image.paste(image, (dx, dy))image = new_image# flip image or not# 随机翻转图片,左边与右边翻转flip = rand() < .5if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT)# distort image# 随机生成hsv值hue = rand(-hue, hue)sat = rand(1, sat) if rand() < .5 else 1/rand(1, sat)val = rand(1, val) if rand() < .5 else 1/rand(1, val)# 将图片的RGB值转成hsv值x = rgb_to_hsv(np.array(image)/255.)# 改变图片的hsv值x[..., 0] += huex[..., 0][x[..., 0] > 1] -= 1x[..., 0][x[..., 0] < 0] += 1x[..., 1] *= satx[..., 2] *= val# 由于hsv值范围为[0, 1],因此将超出这个范围的值调整至范围内x[x > 1] = 1x[x < 0] = 0# 在将hsv值转成RGBimage_data = hsv_to_rgb(x)  # numpy array, 0 to 1# correct boxes# 图片大小、方向被改变后,Gound Truth框也需要调整box_data = np.zeros((max_boxes, 5))if len(box) > 0:# 移动Gound Truth框np.random.shuffle(box)box[:, [0, 2]] = box[:, [0, 2]]*nw/iw + dxbox[:, [1, 3]] = box[:, [1, 3]]*nh/ih + dy# 如果图片翻转,重新计算Gound Truth框x值,if flip: box[:, [0, 2]] = w - box[:, [2, 0]]# 判断调整后的Gound Truth框是否超出边界box[:, 0:2][box[:, 0:2] < 0] = 0box[:, 2][box[:, 2] > w] = wbox[:, 3][box[:, 3] > h] = h# 计算调整后的GT框的高和宽box_w = box[:, 2] - box[:, 0]box_h = box[:, 3] - box[:, 1]# 删除box_w或者box_h<1的框box = box[np.logical_and(box_w > 1, box_h > 1)]  # discard invalid boxif len(box) > max_boxes: box = box[:max_boxes]box_data[:len(box)] = boxreturn image_data, box_data

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内核的Makefile与Kconfig关系解析

在子目录下的Kconfig里添加make menuconfig的选项&#xff08;如图一&#xff09;&#xff0c;并默认设置为y&#xff0c;make menuconfig的菜单里就会有该项并默认为选上状态&#xff0c;make menuconfig配置完之后在.config文件里就有该选项&#xff0c;并等于y&#xff08;如…

C语言extern的用法

在x.c文件里定义如&#xff1a;int x 100; 在x.h文件里声明如&#xff1a;extern int x; 然后在main.c里 #include "x.h"即可 或者直接在main.c里 extern int x; 而不使用#include "x.h"&#xff08;此时x.h里当然也不用extern int x;&#xff09;也…

C语言中.和->区别

结构体变量用 . 运算符来访问结构体的成员 struct A { int a; int b; };A object; object.a 1;指向结构体的指针用->来访问其指向的结构体的成员 A *point malloc(sizeof(struct A)); point->a 1;

Qt中定时器使用的两种方法

https://blog.csdn.net/qq_28877125/article/details/88389559

【深度】韦东山:一文看看尽linux对中断处理的前世今生

https://blog.csdn.net/thisway_diy/article/details/104848034

u-boot中filesize环境变量

U-Boot中的环境命令可以使用$(filesize)来确定刚下载(传输)得到的文件大小. 因为使用类似tftp命令传输文件后&#xff0c;会自动更新filesize环境变量。 如:setenv updaterootfs nand write.yaffs 30000000 200000 $(filesize) 这时如果printenv,会发现updaterootfsnand write…

make menuconfig选择m编译为驱动模块

之前看过各种文章说在make menuconfig的时候把某个选项配置为m&#xff0c;那就是要把该驱动编译为模块&#xff0c;但是在make uImage之后&#xff0c;在对应目录却没有生成.ko文件&#xff08;只有built-in.o&#xff09; 后来才知道是要在执行一遍make modules才会生成.ko文…

Linux下Modules的概念及使用详解

https://www.cnblogs.com/flintlovesam/p/5909782.html https://zhidao.baidu.com/question/270286794.html

QT使用SQLite数据库实现登录功能

QT实现用户登录功能&#xff08;MySQL&#xff09; https://blog.csdn.net/tianya_team/article/details/72566198 QT5中使用SQLite https://blog.csdn.net/weixin_41656968/article/details/80473137 Qt-多界面编程&#xff08;界面切换&#xff09; https://blog.csdn.n…

linux中pthread_join()与pthread_detach()详解

https://blog.csdn.net/weibo1230123/article/details/81410241

linux网络编程函数——地址复用setsockopt()

https://www.cnblogs.com/wujie2014/p/4029992.html

setsockopt()函数功能介绍

https://www.cnblogs.com/eeexu123/p/5275783.html

system函数和signal(SIGCHLD, SIG_DFL)的“固定搭配”

背景知识&#xff1a; 子进程先于父进程结束时&#xff0c;会给父进程发送SIGCHLD信号 如果 1、父进程没有忽略SGICHLD信号; 或…

信号量释放和等待函数sem_post()和sem_wait()

信号量&#xff1a; 信号量是IPC结构中的一种&#xff0c;是进程间通信的一种方法&#xff0c;也可以解决同一进程不同线程之间的通信问题。它是用来保证两个或多个关键代码段不被并发调用&#xff0c;防止多个进程同时对共享资源进行操作。 原理&#xff1a; 在进入一个关键代…

信号量sem_init,sem_wait,sem_post

https://youth.blog.csdn.net/article/details/78318932?utm_mediumdistribute.pc_relevant.none-task-blog-OPENSEARCH-1.control&dist_request_id&depth_1-utm_sourcedistribute.pc_relevant.none-task-blog-OPENSEARCH-1.control

QT的foreach用法

https://blog.csdn.net/qq_35488967/article/details/54602752 https://blog.csdn.net/xiaolong361/article/details/89417527

Linux信号之signal函数

1. 信号概述 何为信号&#xff1a;信号就是由用户、系统或进程发送给目标进程的信息&#xff0c;以通知目标进程中某个状态的改变或是异常。 信号产生&#xff1a;总体来说&#xff0c;其产生的条件有两种&#xff0c;分别是&#xff1a;硬件和软件原因&#xff0c;又称为&…

Linux pause函数 详解

int pause(void);   作用&#xff1a;使调用进程&#xff08;线程&#xff09;进入休眠状态&#xff08;就是挂起&#xff09;&#xff1b;直到接收到信号且信号函数成功返回 pause函数才会返回   返回值&#xff1a;始终返回-1  示例代码: #include <sys/types.h>…