Deep3DFaceRecon_pytorch-master项目学习-util.py

"""This script contains basic utilities for Deep3DFaceRecon_pytorch
"""
from __future__ import print_function
import numpy as np
import torch
from PIL import Image
import os
import importlib
import argparse
from argparse import Namespace
import torchvision

#字符串转布尔
def str2bool(v):
	#isinstance用于检查给定对象是否是指定类的实例
    if isinstance(v, bool):
        return v
        
    #lower() 的应用。这个方法返回原始字符串的小写版本
    #然后检查它是否属于一个包含表示布尔值 "True" 的字符串的元组。
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
    	#抛出自定义异常
        raise argparse.ArgumentTypeError('Boolean value expected.')

#**kwargs任意数量的关键字参数
def copyconf(default_opt, **kwargs):
    conf = Namespace(**vars(default_opt))
    for key in kwargs:
        setattr(conf, key, kwargs[key])
    return conf

def genvalconf(train_opt, **kwargs):
    conf = Namespace(**vars(train_opt))
    attr_dict = train_opt.__dict__
    for key, value in attr_dict.items():
        if 'val' in key and key.split('_')[0] in attr_dict:
            setattr(conf, key.split('_')[0], value)

    for key in kwargs:
        setattr(conf, key, kwargs[key])

    return conf
        
def find_class_in_module(target_cls_name, module):
	#这一行将目标类名中的所有下划线(_)替换为空字符串,并将整个字符串转换为小写。
    target_cls_name = target_cls_name.replace('_', '').lower()
    #importlib 库的 import_module 函数来动态导入指定的模块。clslib 现在是一个指向该模块的引用
    clslib = importlib.import_module(module)
    cls = None
    #这一行遍历模块 clslib 的字典属性(__dict__),这个字典包含了模块中定义的所有变量、函数和类。name 是字典中的键(名称),clsobj 是相应的值(对象)。
    for name, clsobj in clslib.__dict__.items():
        if name.lower() == target_cls_name:
            cls = clsobj

    assert cls is not None, "In %s, there should be a class whose name matches %s in lowercase without underscore(_)" % (module, target_cls_name)

    return cls


def tensor2im(input_image, imtype=np.uint8):

    #这一行检查输入的图像是否为 NumPy 数组。如果不是 NumPy 数组。
    if not isinstance(input_image, np.ndarray):
    	#如果输入图像是一个 PyTorch 张量,
        if isinstance(input_image, torch.Tensor):  # get the data from a variable
            image_tensor = input_image.data
        else:
            return input_image
        #将 image_tensor 裁剪到 [0, 1] 范围,将其从 GPU(如果在 GPU 上)移动到 CPU,将其转换为 float 类型,然后将其从张量转换为 NumPy 数组,赋值给 image_numpy。
        image_numpy = image_tensor.clamp(0.0, 1.0).cpu().float().numpy()

		#如果图像是灰度图,使用 np.tile() 函数将其复制成一个 3 通道的 RGB 图像
        if image_numpy.shape[0] == 1:  # grayscale to RGB
            image_numpy = np.tile(image_numpy, (3, 1, 1))
        #使用 np.transpose() 函数将图像数组的维度顺序从 (通道, 高度, 宽度) 转换为 (高度, 宽度, 通道),并将像素值的范围从 [0, 1] 缩放到 [0, 255]。
        image_numpy = np.transpose(image_numpy, (1, 2, 0)) * 255.0  
    else:  # if it is a numpy array, do nothing
        image_numpy = input_image
    return image_numpy.astype(imtype)

#计算并打印神经网络中所有参数梯度的平均绝对值
def diagnose_network(net, name='network'):
    mean = 0.0
    count = 0
    #遍历网络中的每个参数。
    for param in net.parameters():
    	#如果当前参数的梯度非空,则计算梯度的绝对值,然后计算其平均值,并将其累加到 mean 变量中。
        if param.grad is not None:
            mean += torch.mean(torch.abs(param.grad.data))
            count += 1
    if count > 0:
        mean = mean / count
    print(name)
    print(mean)

#将输入的 NumPy 图像数组保存到磁盘上的指定路径
#aspect_ratio(宽高比,默认为 1.0,表示不改变宽高比)。
def save_image(image_numpy, image_path, aspect_ratio=1.0):
	#将 NumPy 图像数组转换为 PIL 图像对象:使用 PIL 提供的方法来操作和保存图像。
    image_pil = Image.fromarray(image_numpy)
    h, w, _ = image_numpy.shape

    if aspect_ratio is None:
        pass
    #如果宽高比大于 1.0,将图像宽度乘以宽高比,然后调整图像大小
    #使用 PIL 图像对象的 resize() 方法调整图像大小,新的宽度为 int(w * aspect_ratio)。
    #这里使用 BICUBIC 插值方法进行调整。
    elif aspect_ratio > 1.0:
        image_pil = image_pil.resize((h, int(w * aspect_ratio)), Image.BICUBIC)
    elif aspect_ratio < 1.0:
        image_pil = image_pil.resize((int(h / aspect_ratio), w), Image.BICUBIC)
    image_pil.save(image_path)

#用于打印输入 NumPy 数组的一些统计信息
def print_numpy(x, val=True, shp=False):
    x = x.astype(np.float64)
    if shp:
        print('shape,', x.shape)
    if val:
        x = x.flatten()
        print('mean = %3.3f, min = %3.3f, max = %3.3f, median = %3.3f, std=%3.3f' % (
            np.mean(x), np.min(x), np.max(x), np.median(x), np.std(x)))

#用于创建一个或多个不存在的空目录。让我们逐句解释这段代码:
def mkdirs(paths):

    if isinstance(paths, list) and not isinstance(paths, str):
        for path in paths:
            mkdir(path)
    else:
        mkdir(paths)

#其目的是在指定路径不存在时创建一个空目录
def mkdir(path):
	#检查传入的 path 是否已经存在
    if not os.path.exists(path):
    	#创建目录
        os.makedirs(path)

#调整张量中每个图像的大小,并返回一个调整后的张量。
def correct_resize_label(t, size):
    device = t.device#获取输入张量 t 的设备(CPU 或 GPU)
    t = t.detach().cpu()
    resized = []
    for i in range(t.size(0)):
        one_t = t[i, :1]
        one_np = np.transpose(one_t.numpy().astype(np.uint8), (1, 2, 0))
        one_np = one_np[:, :, 0]
        one_image = Image.fromarray(one_np).resize(size, Image.NEAREST)
        #将调整大小后的 PIL.Image 对象转换回 NumPy 数组,然后转换为 Torch 张量,并将数据类型设置为 long
        resized_t = torch.from_numpy(np.array(one_image)).long()
        
        resized.append(resized_t)
    return torch.stack(resized, dim=0).to(device)

#它用于将输入的 PyTorch 张量(图像)调整到指定的尺寸
def correct_resize(t, size, mode=Image.BICUBIC):
    device = t.device
    t = t.detach().cpu()
    resized = []
    for i in range(t.size(0)):
        one_t = t[i:i + 1]
        one_image = Image.fromarray(tensor2im(one_t)).resize(size, Image.BICUBIC)
        #将张量的值范围从 [0, 1] 调整为 [-1, 1]
        resized_t = torchvision.transforms.functional.to_tensor(one_image) * 2 - 1.0
        resized.append(resized_t)
    return torch.stack(resized, dim=0).to(device)


#用于在图像上绘制人脸关键点,landmark(关键点坐标)、step(用于定义关键点绘制时的像素步长,默认为 2)。
def draw_landmarks(img, landmark, color='r', step=2):

    if color =='r':
        c = np.array([255., 0, 0])
    else:
        c = np.array([0, 0, 255.])

    _, H, W, _ = img.shape
    img, landmark = img.copy(), landmark.copy()
    #landmark[..., 1] 选取了所有关键点的 y 坐标
    landmark[..., 1] = H - 1 - landmark[..., 1]
    #将关键点坐标四舍五入并转换为 int32 类型。
    landmark = np.round(landmark).astype(np.int32)
    #遍历所有关键点。
    for i in range(landmark.shape[1]):
        x, y = landmark[:, i, 0], landmark[:, i, 1]
        #遍历关键点周围的像素,从 -step 到 step(不包括 step)。
        for j in range(-step, step):
        	#遍历关键点周围的像素
            for k in range(-step, step):
            	#计算新的 x 坐标 u,将其限制在图像宽度范围内
                u = np.clip(x + j, 0, W - 1)
                #计算新的 y 坐标 v,将其限制在图像高度范围内。
                v = np.clip(y + k, 0, H - 1)
                for m in range(landmark.shape[0]):
                    img[m, v[m], u[m]] = c
    return img

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
无人机视觉检测和跟踪yolov5_deepsort_pytorch-master-newest-drone.zip 是一个基于深度学习模型的无人机目标检测和跟踪工具包。它使用了YOLOv5和DeepSORT这两个先进的算法来实现对无人机进行实时监测和跟踪。下面是对该工具包的详细解释: YOLOv5是一种在计算机视觉领域非常先进的目标检测算法,它使用深度卷积神经网络来实现实时目标检测。该工具包使用YOLOv5来对图像或视频中的无人机进行快速而准确的检测和定位。 DeepSORT是一种在多目标跟踪领域非常流行的算法,它结合了深度学习和卡尔曼滤波器来实现对目标的持续跟踪。该工具包使用DeepSORT来对检测到的无人机进行跟踪,并提供准确的目标轨迹信息。 这个工具包的主要特点包括:高效的无人机检测和定位、准确的目标跟踪、实时处理能力以及易于使用的界面。使用该工具包,我们可以实时地监测无人机的位置和动态信息,同时可以对其进行跟踪和记录。这对于无人机安全监控、无人机航拍和无人机调度等应用非常有用。 值得注意的是,使用该工具包需要一定的计算资源和图像处理能力。同时,对于不同的无人机视觉场景和环境,可能需要对该工具包进行一定的参数调整和优化,以获得更好的检测和跟踪效果。 综上所述,无人机视觉检测和跟踪yolov5_deepsort_pytorch-master-newest-drone.zip 是一个强大而高效的工具包,可以实现对无人机的实时检测和跟踪。它基于YOLOv5和DeepSORT算法,提供准确的无人机定位和目标轨迹信息。同时,使用该工具包需要一定的计算资源和参数调整。对于无人机安全监控、无人机航拍和无人机调度等应用具有重要意义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值