YOLOv5 分类模型 预处理 OpenCV实现

news2024/9/28 23:32:47

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)/std
    images = images.transpose((2, 0, 1))# HWC to CHW
    images = 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 img
        if w < h:
            ow = size
            oh = int(size * h / w)
        else:
            oh = size
            ow = 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_size
    i = 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 numbers


classes_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)/std
    images = images.transpose((2, 0, 1))# HWC to CHW
    images = np.ascontiguousarray(images)
    return images

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 img
        if w < h:
            ow = size
            oh = int(size * h / w)
        else:
            oh = size
            ow = 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

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_size
    i = 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 = root

        if classes_name is None or not classes_name:
            classes, class_to_idx = self.find_classes(self.root)
            print("not classes_name")

        else:
            classes = classes_name
            class_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 = classes
        self.class_to_idx = class_to_idx
        self.samples = samples
        self.targets = [s[1] for s in samples]

    @staticmethod
    def 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):
                continue
            for 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_index
                        instances.append(item)

                        if target_class not in available_classes:
                            available_classes.add(target_class)

        empty_classes = set(class_to_idx.keys()) - available_classes
        if empty_classes:
            msg = f"Found no valid file for the classes {', '.join(sorted(empty_classes))}. "

        return instances

    def 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_idx

    def __getitem__(self, index: int) -> Tuple[Any, Any]:

        path, target = self.samples[index]
        sample = self.loader(path)

        return sample, target

    def __len__(self) -> int:
        return len(self.samples)

    def loader(self, path):
        print("path:", path)
        img = cv2.imread(path)  # BGR HWC
        img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#RGB
        print("type:",type(img))
        return img


def 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 tensor
    images = images.unsqueeze(0).to("cpu")
 
    print(images.shape)


        
    t1 = time_sync()
    images = images.to(device, non_blocking=True)
    t2 = time_sync()
    # dt[0] += t2 - t1

    y = model(images)
    y=y.numpy()
   
    print("y:", y)
    t3 = time_sync()
    # dt[1] += t3 - t2

    tmp1=y.argsort()[:,::-1][:, :5]
   
    print("tmp1:", tmp1)
    pred.append(tmp1)

    print("labels:", labels)

    
    targets.append(labels)

    print("for pred:", pred)  # list
    print("for targets:", targets)  # list

    # dt[2] += time_sync() - t3


pred, 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.coloradmin.cn/o/1242689.html

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

相关文章

OpenCV入门10——特征点检测与匹配

文章目录 特征检测的基本概念Harris角点检测Shi-Tomasi角点检测SIFT关键点检测SIFT计算描述子SURF特征检测OBR特征检测暴力特征匹配FLANN特征匹配实战flann特征匹配图像查找图像拼接基础知识图像拼接实战 特征点检测与匹配是计算机视觉中非常重要的内容。不是所有图像操作都是对…

腾讯又出王炸产品!使用混元大模型进行数据报表测试

最近腾讯出了自己的大模型&#xff0c;命名混元。 现在已经开始内测&#xff0c;感谢腾讯小伙伴卢晓明同学帮我们提前申请到了内测机会&#xff0c;接下来我们用腾讯混元大模型与实际工作结合&#xff0c;开始我的报表测试之旅。 腾讯混元大模型官方入口:https://hunyuan.ten…

深入了解前馈网络、CNN、RNN 和 Hugging Face 的 Transformer 技术!

一、说明 本篇在此对自然语言模型做一个简短总结&#xff0c;从CNN\RNN\变形金刚&#xff0c;和抱脸的变形金刚库说起。 二、基本前馈神经网络&#xff1a; 让我们分解一个基本的前馈神经网络&#xff0c;也称为多层感知器&#xff08;MLP&#xff09;。此代码示例将&#xff1…

玻色量子“揭秘”之集合划分问题与QUBO建模

摘要&#xff1a;集合划分问题&#xff08;Set Partitioning Problem&#xff09;是一种组合优化问题&#xff0c;其中给定一个集合S和其若干个不同的子集S1&#xff0c;S2&#xff0c;...&#xff0c;Sn后&#xff0c;需要找到子集的有效组合&#xff0c;使得集合S的每个元素正…

高通Camera HAL3: CamX、Chi-CDK要点

目录 一、概述 二、目录 三、CamX组件之前的关系 一、概述 高通CamX架构是高通实现的相机HAL3架构&#xff0c;被各OEM厂商广泛采用。 二、目录 代码位于vendor/qcom/proprietary下&#xff1a; camx&#xff1a;通用功能性接口的代码实现集合chi-cdk&#xff1a;可定制化…

shell循环语句 for while until

目录 什么是循环语句 概念 for循环 格式 while循环 格式 until 循环 格式 实验 for &#xff08;1&#xff09;计算1到100的和 ​编辑 &#xff08;2&#xff09;100以内的偶数 &#xff08;从0开始到100结束&#xff0c;每次加2步 打印的都是偶数&#xff09; &…

ELK架构

经典的ELK 经典的ELK主要是由Filebeat Logstash Elasticsearch Kibana组成&#xff0c;如下图&#xff1a;&#xff08;早期的ELK只有Logstash Elasticsearch Kibana&#xff09; 此架构主要适用于数据量小的开发环境&#xff0c;存在数据丢失的危险。 整合消息队列Ngin…

Spring框架学习 -- 读取和存储Bean对象

目录 &#x1f680;&#x1f680; 回顾 getBean()方法的使用 根据name来获取对象 再谈getBean() (1) 配置扫描路径 (2) 添加注解 ① spring注解简介 ② 对类注解的使用 ③ 注解Bean对象的命名问题 ④ 方法加Bean注解 (3) Bean 注解的重命名 (4) 获取Bean对象 -- …

投标文件的注意事项

一、检查标书 1.1有时候标书需要从别的地方复制黏贴文件&#xff0c;记住复制内容可以&#xff0c;但是不要复制“落款和时间”的格式&#xff0c;落款和时间的格式借鉴你的招标文件中给响应文件格式的落款和时间&#xff0c;切记&#xff01; 1.2检查标书是否有空页&#xf…

数据中心运维管理:从人工到智能需要走几步?

一切的变化来自于数据中心规模、复杂度、设备多样性的挑战&#xff0c;将运维平台的重要性推向历史高点。 此外&#xff0c;基于业务连续性方面的考虑&#xff0c;分布式数据中心成为越来越多客户的选择。 一、数据中心面临的挑战 运维管理分散&#xff0c;缺乏统一的管理 I…

Linux:设置Ubuntu的root用户密码

执行以下命令&#xff1a; 给root用户设置密码 sudo passwd 输入两次密码 切换root su root 退出root用户 exit

地埋式积水监测仪厂家直销推荐,致力于积水监测

地埋式积水监测仪是一种高科技设备&#xff0c;能够实时监测地面积水深度&#xff0c;并及时发出预警信息&#xff0c;有效避免因积水而产生的安全隐患。这种智能监测仪可以安装在城市道路、立交桥、地下车库等易积水地势较低的地方&#xff0c;以确保及时监测特殊地段的积水&a…

【Sorted Set】Redis常用数据类型: ZSet [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 目录 ⑤Redis Zset 操作命令汇总1. zadd 添加或…

APM工具skywalking部署

一 整体架构 整个架构&#xff0c;分成上、下、左、右四部分&#xff1a; 上部分 Agent &#xff1a;负责从应用中&#xff0c;收集链路信息&#xff0c;发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 数据信息。而我们目前采用的是&…

css渐变详解(重复性线性渐变、径向渐变、重复性径向渐变的使用)

目录 线性渐变 重复性线性渐变 径向渐变 重复性径向渐变的使用 线性渐变 线性渐变是向下、向上、向左、向右、对角方向的颜色渐变。 其语法格式为&#xff1a; background-image: linear-gradient(side-or-corner|angle, linear-color-stop); 参数说明如下&#xff1a; …

mongo DB -- aggregate分组查询后字段展示

一、分组查询 在mongoDB中可以使用aggregate中的$group操作对集合中的文档进行分组,但是查询后的数据不显示其他字段,只显示分组字段 aggregate进行分组示例 db.collection.aggregate([{$group: {_id: "$field"}},]) 查询后显示 展开只显示两个字段 二、显示所有字段…

10.分组循环练习题

分组循环 https://leetcode.cn/problems/longest-even-odd-subarray-with-threshold/solutions/2528771/jiao-ni-yi-ci-xing-ba-dai-ma-xie-dui-on-zuspx/?envTypedaily-question&envId2023-11-16 分组循环 适用场景&#xff1a; 按照题目要求&#xff0c;数组会被分割成若…

微信运营神器:从群发到批量添加,让你的微信营销更轻松

在这个数字化时代&#xff0c;微信已经成为了我们生活中不可或缺的一部分。对于许多企业和个人来说&#xff0c;微信营销也是非常重要的一部分。但是&#xff0c;微信营销并不是一件容易的事情&#xff0c;需要花费大量的时间和精力。为了解决这个问题&#xff0c;今天我们将向…

邻趣连接力:如何无代码集成CRM、电商平台和营销系统,提升广告推广效率

连接即服务&#xff1a;邻趣无代码集成方法 传统的电商系统集成过程需要大量的时间和资源进行API开发&#xff0c;这不仅耗时耗力&#xff0c;还需要专业的技术团队支持。然而&#xff0c;邻趣通过提供一种无需API开发的连接方法&#xff0c;极大地简化了整个集成过程。商家只…

3D人脸扫描设备助力企业家数字人复刻,打破商业边界

京都薇薇推出数字人VN&#xff0c;以京都薇薇董事长为原型制作&#xff0c;赋能品牌直播、短片宣传、线上面诊等活动&#xff0c;进一步增强消费者对品牌的交互体验&#xff0c;把元宇宙与品牌相融合&#xff0c;推动品牌线上服务与线下服务实现数字一体化&#xff0c;打造一个…