当前位置: 首页 > news >正文

YOLOv5 分类模型 预处理 OpenCV实现

YOLOv5 分类模型 预处理 OpenCV实现

flyfish

YOLOv5 分类模型 预处理 PIL 实现
YOLOv5 分类模型 OpenCV和PIL两者实现预处理的差异

YOLOv5 分类模型 数据集加载 1 样本处理
YOLOv5 分类模型 数据集加载 2 切片处理
YOLOv5 分类模型 数据集加载 3 自定义类别

YOLOv5 分类模型的预处理(1) Resize 和 CenterCrop
YOLOv5 分类模型的预处理(2)ToTensor 和 Normalize

YOLOv5 分类模型 Top 1和Top 5 指标说明
YOLOv5 分类模型 Top 1和Top 5 指标实现

判断图像是否是np.ndarray类型和维度

OpenCV读取一张图像时,类型类型就是<class 'numpy.ndarray'>,这里判断图像是否是np.ndarray类型
dim是dimension维度的缩写,shape属性的长度也是它的ndim
灰度图的shape为HW,二个维度
RGB图的shape为HWC,三个维度
在这里插入图片描述

def _is_numpy_image(img):return isinstance(img, np.ndarray) and (img.ndim in {2, 3})

实现ToTensor和Normalize

def totensor_normalize(img):print("preprocess:",img.shape)images = (img/255-mean)/stdimages = images.transpose((2, 0, 1))# HWC to CHWimages = np.ascontiguousarray(images)return images

实现Resize

插值可以是以下参数

# 'nearest': cv2.INTER_NEAREST,
# 'bilinear': cv2.INTER_LINEAR,
# 'area': cv2.INTER_AREA,
# 'bicubic': cv2.INTER_CUBIC,
# 'lanczos': cv2.INTER_LANCZOS4
def resize(img, size, interpolation=cv2.INTER_LINEAR):r"""Resize the input numpy ndarray to the given size.Args:img (numpy ndarray): Image to be resized.size: like pytroch about size interpretation flyfish.interpolation (int, optional): Desired interpolation. Default is``cv2.INTER_LINEAR``  Returns:numpy Image: Resized image.like opencv"""if not _is_numpy_image(img):raise TypeError('img should be numpy image. Got {}'.format(type(img)))if not (isinstance(size, int) or (isinstance(size, collections.abc.Iterable) and len(size) == 2)):raise TypeError('Got inappropriate size arg: {}'.format(size))h, w = img.shape[0], img.shape[1]if isinstance(size, int):if (w <= h and w == size) or (h <= w and h == size):return imgif w < h:ow = sizeoh = int(size * h / w)else:oh = sizeow = int(size * w / h)else:ow, oh = size[1], size[0]output = cv2.resize(img, dsize=(ow, oh), interpolation=interpolation)if img.shape[2] == 1:return output[:, :, np.newaxis]else:return output

实现CenterCrop

def crop(img, i, j, h, w):"""Crop the given Image flyfish.Args:img (numpy ndarray): Image to be cropped.i: Upper pixel coordinate.j: Left pixel coordinate.h: Height of the cropped image.w: Width of the cropped image.Returns:numpy ndarray: Cropped image."""if not _is_numpy_image(img):raise TypeError('img should be numpy image. Got {}'.format(type(img)))return img[i:i + h, j:j + w, :]def center_crop(img, output_size):if isinstance(output_size, numbers.Number):output_size = (int(output_size), int(output_size))h, w = img.shape[0:2]th, tw = output_sizei = int(round((h - th) / 2.))j = int(round((w - tw) / 2.))return crop(img, i, j, th, tw)

完整

import time
from models.common import DetectMultiBackend
import os
import os.path
from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union
import cv2
import numpy as np
import collections
import torch
import numbersclasses_name=['n02086240', 'n02087394', 'n02088364', 'n02089973', 'n02093754', 'n02096294', 'n02099601', 'n02105641', 'n02111889', 'n02115641']mean=[0.485, 0.456, 0.406]
std=[0.229, 0.224, 0.225]def _is_numpy_image(img):return isinstance(img, np.ndarray) and (img.ndim in {2, 3})def totensor_normalize(img):print("preprocess:",img.shape)images = (img/255-mean)/stdimages = images.transpose((2, 0, 1))# HWC to CHWimages = np.ascontiguousarray(images)return imagesdef resize(img, size, interpolation=cv2.INTER_LINEAR):r"""Resize the input numpy ndarray to the given size.Args:img (numpy ndarray): Image to be resized.size: like pytroch about size interpretation flyfish.interpolation (int, optional): Desired interpolation. Default is``cv2.INTER_LINEAR``  Returns:numpy Image: Resized image.like opencv"""if not _is_numpy_image(img):raise TypeError('img should be numpy image. Got {}'.format(type(img)))if not (isinstance(size, int) or (isinstance(size, collections.abc.Iterable) and len(size) == 2)):raise TypeError('Got inappropriate size arg: {}'.format(size))h, w = img.shape[0], img.shape[1]if isinstance(size, int):if (w <= h and w == size) or (h <= w and h == size):return imgif w < h:ow = sizeoh = int(size * h / w)else:oh = sizeow = int(size * w / h)else:ow, oh = size[1], size[0]output = cv2.resize(img, dsize=(ow, oh), interpolation=interpolation)if img.shape[2] == 1:return output[:, :, np.newaxis]else:return outputdef crop(img, i, j, h, w):"""Crop the given Image flyfish.Args:img (numpy ndarray): Image to be cropped.i: Upper pixel coordinate.j: Left pixel coordinate.h: Height of the cropped image.w: Width of the cropped image.Returns:numpy ndarray: Cropped image."""if not _is_numpy_image(img):raise TypeError('img should be numpy image. Got {}'.format(type(img)))return img[i:i + h, j:j + w, :]def center_crop(img, output_size):if isinstance(output_size, numbers.Number):output_size = (int(output_size), int(output_size))h, w = img.shape[0:2]th, tw = output_sizei = int(round((h - th) / 2.))j = int(round((w - tw) / 2.))return crop(img, i, j, th, tw)class DatasetFolder:def __init__(self,root: str,) -> None:self.root = rootif classes_name is None or not classes_name:classes, class_to_idx = self.find_classes(self.root)print("not classes_name")else:classes = classes_nameclass_to_idx ={cls_name: i for i, cls_name in enumerate(classes)}print("is classes_name")print("classes:",classes)print("class_to_idx:",class_to_idx)samples = self.make_dataset(self.root, class_to_idx)self.classes = classesself.class_to_idx = class_to_idxself.samples = samplesself.targets = [s[1] for s in samples]@staticmethoddef make_dataset(directory: str,class_to_idx: Optional[Dict[str, int]] = None,) -> List[Tuple[str, int]]:directory = os.path.expanduser(directory)if class_to_idx is None:_, class_to_idx = self.find_classes(directory)elif not class_to_idx:raise ValueError("'class_to_index' must have at least one entry to collect any samples.")instances = []available_classes = set()for target_class in sorted(class_to_idx.keys()):class_index = class_to_idx[target_class]target_dir = os.path.join(directory, target_class)if not os.path.isdir(target_dir):continuefor root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):for fname in sorted(fnames):path = os.path.join(root, fname)if 1:  # 验证:item = path, class_indexinstances.append(item)if target_class not in available_classes:available_classes.add(target_class)empty_classes = set(class_to_idx.keys()) - available_classesif empty_classes:msg = f"Found no valid file for the classes {', '.join(sorted(empty_classes))}. "return instancesdef find_classes(self, directory: str) -> Tuple[List[str], Dict[str, int]]:classes = sorted(entry.name for entry in os.scandir(directory) if entry.is_dir())if not classes:raise FileNotFoundError(f"Couldn't find any class folder in {directory}.")class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}return classes, class_to_idxdef __getitem__(self, index: int) -> Tuple[Any, Any]:path, target = self.samples[index]sample = self.loader(path)return sample, targetdef __len__(self) -> int:return len(self.samples)def loader(self, path):print("path:", path)img = cv2.imread(path)  # BGR HWCimg=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#RGBprint("type:",type(img))return imgdef time_sync():return time.time()dataset = DatasetFolder(root="/media/flyfish/datasets/imagewoof/val")
weights = "/home/classes.pt"
device = "cpu"
model = DetectMultiBackend(weights, device=device, dnn=False, fp16=False)
model.eval()def classify_transforms(img):img=resize(img,224)img=center_crop(img,224)img=totensor_normalize(img)return img;pred, targets, loss, dt = [], [], 0, [0.0, 0.0, 0.0]
# current batch size =1
for i, (images, labels) in enumerate(dataset):print("i:", i)print(images.shape, labels)im = classify_transforms(images)images=torch.from_numpy(im).to(torch.float32) # numpy to tensorimages = images.unsqueeze(0).to("cpu")print(images.shape)t1 = time_sync()images = images.to(device, non_blocking=True)t2 = time_sync()# dt[0] += t2 - t1y = model(images)y=y.numpy()print("y:", y)t3 = time_sync()# dt[1] += t3 - t2tmp1=y.argsort()[:,::-1][:, :5]print("tmp1:", tmp1)pred.append(tmp1)print("labels:", labels)targets.append(labels)print("for pred:", pred)  # listprint("for targets:", targets)  # list# dt[2] += time_sync() - t3pred, targets = np.concatenate(pred), np.array(targets)
print("pred:", pred)
print("pred:", pred.shape)
print("targets:", targets)
print("targets:", targets.shape)
correct = ((targets[:, None] == pred)).astype(np.float32)
print("correct:", correct.shape)
print("correct:", correct)
acc = np.stack((correct[:, 0], correct.max(1)), axis=1)  # (top1, top5) accuracy
print("acc:", acc.shape)
print("acc:", acc)
top = acc.mean(0)
print("top1:", top[0])
print("top5:", top[1])

结果

pred: [[0 3 6 2 1][0 7 2 9 3][0 5 6 2 9]...[9 8 7 6 1][9 3 6 7 0][9 5 0 2 7]]
pred: (3929, 5)
targets: [0 0 0 ... 9 9 9]
targets: (3929,)
correct: (3929, 5)
correct: [[          1           0           0           0           0][          1           0           0           0           0][          1           0           0           0           0]...[          1           0           0           0           0][          1           0           0           0           0][          1           0           0           0           0]]
acc: (3929, 2)
acc: [[          1           1][          1           1][          1           1]...[          1           1][          1           1][          1           1]]
top1: 0.86230594
top5: 0.98167473
http://www.lryc.cn/news/242221.html

相关文章:

  • 在arm 64 环境下使用halcon算法
  • H5(uniapp)中使用echarts
  • QLineEdit设置掩码Ip
  • 开源语音大语言模型来了!阿里基于Qwen-Chat提出Qwen-Audio!
  • 缓存雪崩、击穿、穿透及解决方案_保证缓存和数据库一致性
  • 仿 美图 / 饿了么,店铺详情页功能
  • Redis Cluster主从模式详解
  • Linux技能篇-非交互式修改密码
  • 记一次docker服务启动失败解决过程
  • npm ERR! node-sass@4.13.0 postinstall: `node scripts/build.js`
  • Java定时任务 ScheduledThreadPoolExecutor
  • Android Studio 显示build variants工具栏
  • c++八股文记录
  • C++ 指针进阶:动态分配内存
  • 点大商城V2.5.3分包小程序端+小程序上传提示限制分包制作教程
  • AUTOSAR汽车电子嵌入式编程精讲300篇-基于机器学习的车载 CAN 网络入侵检测
  • Jetson orin(Ubuntu20.04)不接显示器无法输出VNC图像解决办法以及vnc安装记录
  • LeetCode Hot100 108.将有序数组转为二叉搜索树
  • 微机原理_3
  • 4.操作系统常见面试题(2)
  • springboot 开启和关闭kafka消费
  • org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
  • 系统安全测试要怎么做?
  • Golang并发模型:Goroutine 与 Channel 初探
  • 批量添加PPT备注
  • 数据挖掘之PCA-主成分分析
  • 人工智能-注意力机制之注意力汇聚:Nadaraya-Watson 核回归
  • <HarmonyOS第一课>1·运行Hello World【课后考核】
  • Ubuntu18.04安装A-Loam保姆级教程
  • 重生之我是一名程序员 40 ——字符串函数(1)