yolov5-master记录

一、argparse常见的用法

需要

import argparse 

argparse可以让命令行参数传入python程序中。

import argparse

if __name__=="__main__":
    #创建参数缓冲器
    parser = argparse.ArgumentParser()
    parser.add_argument('a', type=int, help='this is arg a')
    parser.add_argument('b', type=float, help='this is arg b')
    #获取所有参数
    args = parser.parse_args()
    #以这种方式访问参数
    print(args.a)
    print(args.b)

调用argparse.ArgumentParser()可以创建参数缓冲器,在其中添加参数,并调用parse_args方法将参数转移到args这个类变量中。之后可以使用 . 运算符访问。

python test_argparser.py 1 1.5

按照这样的方式调用程序,1为赋予a的值,1.5为赋予b的值

将a和b这样的参数加上--可以使得它变为可选参数,然后可以规定其缺省值。

import argparse

if __name__=="__main__":
    #创建参数缓冲器
    parser = argparse.ArgumentParser()
    parser.add_argument('--a', default=0, type=int, help='this is arg a')
    parser.add_argument('--b', default=0.0, type=float, help='this is arg b')
    #获取所有参数
    args = parser.parse_args()
    #以这种方式访问参数
    print(args.a)
    print(args.b)

注意看,args仍然按原来一样调用a和b,但是命令行输入要改为:

python test_argparser.py --a 1 --b 1.5

action='store_true'的参数设置可以把当前参数设置为bool型,当命令行中输入对应参数,则自动把该参数的值设为True

import argparse

if __name__=="__main__":
    #创建参数缓冲器
    parser = argparse.ArgumentParser()
    parser.add_argument('--a', default=0, type=int, help='this is arg a')
    parser.add_argument('--b', default=0.0, type=float, help='this is arg b')
    parser.add_argument('--c',action='store_true')
    #获取所有参数
    args = parser.parse_args()
    #以这种方式访问参数
    print(args.c)

(d2l_exercise) C:\Users\23807\exercise>python test_argparser.py --c
True

(d2l_exercise) C:\Users\23807\exercise>python test_argparser.py
False

二、杂项

1、isnumeric()方法

str的isnumeric方法可以检查字符串是否为整数

period="23"
print(period.isnumeric())

True

2、ndimension()方法

tensor张量使用该方法可以返回其维度大小 

3、unsqueezed()方法

可以用于拓展张量的维度,unsqueezed(0)可以把一个3*2*2的张量拓展为1*3*2*2

4、torch的stack()方法

用于堆叠张量,比如有两个3*4的张量,可以把它们堆叠为2*3*4的张量(堆叠维度为0)。当然也可以在别的维度堆叠,默认堆叠的维度为0。

5、torch的mean()方法

可以对特定维度取平均值。如有2*3*4的张量,对dim=0取平均值,就可以得到3*4向量,而这个3*4矩阵的每个值为之前两个3*4向量对应位置的平均值!

默认,会对所有值取平均值,得到一个常数。可以规定对哪些维度取平均值。

import torch

a1=torch.arange(12,dtype=torch.float32).reshape((3,4))
a2=torch.arange(12,dtype=torch.float32).reshape((3,4))*-1.5
a=[a1,a2]
b=torch.stack(a)
c=b.mean(0)
print(b)
print(c)

tensor([[[  0.0000,   1.0000,   2.0000,   3.0000],
         [  4.0000,   5.0000,   6.0000,   7.0000],
         [  8.0000,   9.0000,  10.0000,  11.0000]],

        [[ -0.0000,  -1.5000,  -3.0000,  -4.5000],
         [ -6.0000,  -7.5000,  -9.0000, -10.5000],
         [-12.0000, -13.5000, -15.0000, -16.5000]]])
tensor([[ 0.0000, -0.2500, -0.5000, -0.7500],
        [-1.0000, -1.2500, -1.5000, -1.7500],
        [-2.0000, -2.2500, -2.5000, -2.7500]])

6、hasattr()方法

python的hassttr方法,第一个参数是对象/类名称,第二个参数是参数名称(用引号括起来)

class Person:
    name = "John"
    age = 36
    country = "Norway"

x = hasattr(Person, 'age')

7、按值传参/按引用传参
import numpy as np
import torch

def plus(a):
    if isinstance(a,list):
        for i in range(len(a)):
            a[i]=a[i]+3
    else:
        a=a+3

def minus(b):
    for i in b:
        i=i-3

def newplus(a):
    for i in range(len(a)):
        a[i]=a[i]+3

a=3
b=[1,2]
c=np.array(b)
d=torch.tensor(b)
plus(a)
plus(b)
plus(c)
plus(d)
print(a)
print(b)
print(c)
print(d)
minus(b)
minus(c)
minus(d)
print(b)
print(c)
print(d)
newplus(b)
newplus(c)
newplus(d)
print(b)
print(c)
print(d)

3
[4, 5]
[1 2]
tensor([1, 2])
[4, 5]
[1 2]
tensor([1, 2])
[7, 8]
[4 5]
tensor([4, 5])

区分一下,python的这一块比较乱。

三、使用Thread类

需要

import threading 

Thread类

thread = Thread(target=self.update, args=([i, cap]), daemon=True)

target用于确定需要运行的函数名称

args通过元组传入函数运行的参数

daemon用于确定该线程是否为守护线程(即主线程结束,子线程随之结束的线程)

thread = Thread(target=self.update, args=([i, cap]), daemon=True)
thread.start()

start()方法

调用Thread实例的start方法,会启动线程的活动。 每个线程对象最多只能调用一次。多次调用将引发RuntimeError错误。
线程启动后,将在子线程中,执行线程target传入的函数。

四、使用cv2库打开摄像头

需要

import cv2

capture = cv2.VideoCapture(index)

capture:作为打开的摄像头的操作句柄

index:摄像头的设备索引,对于笔记本电脑来说,为0时,一般打开的是电脑的内置摄像头,为1时,打开的为外接的摄像头。

import cv2
 
capture = cv2.VideoCapture(0)   # 打开笔记本内置摄像头
while capture.isOpened():      # 笔记本摄像头被打开
    retval, image = capture.read()  # 从摄像头中实时读取画面
    cv2.imshow("Video", image)  # 在窗口显示读取到的视频
    key = cv2.waitKey(1)     # 等待用户按下键盘按键的时间为1毫秒
    if key == 32:        # 如果按键为空格,就跳出循环
        break
capture.release()   # 关闭摄像头
cv2.destroyAllWindows()    # 销毁窗口
read()方法
retval, frame = cap.read()

read()方法可以从摄像头画面中截取帧,返回的第一个参数是bool值,显示是否读取到帧,第二个参数是读取到的图片。但该图片不是numpy形式的!

retrieve()方法

cv2.VideoCapture.retrieve()是OpenCV库中的一个函数,用于从视频中检索帧。该函数的用法如下:

retval, frame = cap.retrieve()

其中,cap是一个cv2.VideoCapture()对象,表示视频文件或摄像头。retval是一个布尔值,表示是否成功检索到帧。frame是一个numpy数组,表示检索到的帧。

这两个方法的区别在于输出形式的不同!

五、LoadStreams类小记

LoadStreams类实际上是一个迭代器。每次返回四个元素、

第一个元素:返回摄像头/视频来源数组,如[1,2,4]

第二个元素:返回经过处理的img图,为numpy形式。(batch_size, channel, height , width)

第三个元素:返回未经处理的img图,为numpy形式。

第四个元素:空/None

注意,以上的处理包括形状比例的缩放和张量的转置。 

img = np.ascontiguousarray(img)

这个函数可以让img在内存中储存在连续的位置,提高处理速度。

六、nn.Modulelist类小记

nn.Modulelist类似nn.Sequential类,它可以包含多个nn.Module子模块,可以像列表一样管理这些子模块。

self.layers = nn.ModuleList([nn.Linear(10, 20), nn.Linear(20, 30)])

如图所示,可以用含有nn.Module对象的列表作为参数,传入Modulelist的构造函数,并创建该类的对象!

1、与nn.Sequential不同,nn.ModuleList可以包含任意数量的子模块,并且可以在运行时动态地添加或删除子模块。

2、nn.ModuleList支持大部分Python列表的操作,如索引、迭代和切片等

我们知道python利用super()调用父类的函数。这个在编写子类的构造函数时常常需要用:

import torch.nn as nn

class MyNetwork(nn.Module):
    def __init__(self):
        super(MyNetwork, self).__init__()
        self.layers = nn.ModuleList([nn.Linear(10, 20), nn.Linear(20, 30)])

    def forward(self, x):
        for layer in self.layers:
            x = layer(x)
        return x

需要注意的是,第一个参数是类名,第二个参数是self。

在python3中,这两个参数可以省略!

七、model小记

yolov5-master的model是一个nn.Modulelist的子类对象,其forward()方法返回一个二长度元组,元组第二个参数可以忽略。

第一个参数是一个1*20160*85的tensor张量,这个张量必须经过Non-Max Suppression处理,得到一个1*n*6的tensor张量。

注意,这个张量标记着检测到的n个物体的6个特征值,分别是:

x_center 横向坐标

y_center 纵向坐标

width 识别框宽度

height 识别框高度

置信度

识别到物体的分类标号

注意,x_center和y_center的原点是图片左上角。

规范化的值应当是0-1之间的小数,但我这里的值仍然是像素! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值