
最近在辅导一些刚入门计算机视觉的同学时发现大家普遍面临一个困境网上资料零散不成体系从CNN基础到Transformer进阶缺少一条清晰的学习路径。本文基于2026年最新技术趋势系统梳理从CNN图像分类到U-Net分割再到ResNet迁移学习与Transformer主流网络的完整知识体系包含大量可运行的代码示例和项目实战。无论你是零基础初学者还是有一定经验想系统提升的开发者都能通过本文建立完整的计算机视觉知识框架掌握各主流网络的实现原理和实战技巧。1. 计算机视觉基础与核心概念1.1 什么是计算机视觉计算机视觉是让机器看懂图像和视频的科学。从简单的图像分类到复杂的自动驾驶场景理解计算机视觉技术已经深入到我们生活的方方面面。传统的图像处理方法依赖手工设计的特征提取器而现代计算机视觉则主要基于深度学习技术。深度学习在计算机视觉中的优势在于能够自动从数据中学习特征表示无需人工设计特征提取器。这种端到端的学习方式大大提升了模型的性能和泛化能力。1.2 计算机视觉的主要任务图像分类是计算机视觉中最基础的任务目标是将图像划分到预定义的类别中。比如识别一张图片中是猫还是狗。图像分类为后续更复杂的任务奠定了基础。目标检测不仅要识别图像中的物体类别还要定位物体的位置通常用边界框表示。常见的应用包括人脸检测、车辆检测等。语义分割需要对图像中的每个像素进行分类将图像分割成具有语义意义的区域。这在医疗影像分析、自动驾驶等领域有重要应用。实例分割是目标检测和语义分割的结合既要检测出每个物体实例又要对每个实例进行像素级分割。1.3 深度学习在计算机视觉中的发展历程2012年AlexNet在ImageNet竞赛中的突破性表现标志着深度学习在计算机视觉领域的崛起。随后VGG、GoogLeNet、ResNet等网络架构不断推陈出新在准确率和效率方面都取得了显著提升。2020年后Transformer架构从自然语言处理领域迁移到计算机视觉领域出现了Vision Transformer等模型开启了视觉领域的新篇章。如今卷积神经网络与Transformer的融合成为主流趋势。2. 环境准备与工具配置2.1 基础环境搭建进行计算机视觉开发首先需要配置合适的编程环境。推荐使用Python 3.8版本配合PyTorch或TensorFlow深度学习框架。# 创建conda环境 conda create -n cv-tutorial python3.8 conda activate cv-tutorial # 安装PyTorch根据CUDA版本选择 pip install torch torchvision torchaudio # 或者安装TensorFlow pip install tensorflow # 安装计算机视觉相关库 pip install opencv-python pillow matplotlib numpy scikit-learn2.2 开发工具配置Jupyter Notebook适合进行实验和可视化PyCharm或VS Code适合大型项目开发。建议配置GPU环境以加速模型训练对于初学者可以使用Google Colab提供的免费GPU资源。# 检查GPU是否可用 import torch print(fPyTorch版本: {torch.__version__}) print(fCUDA是否可用: {torch.cuda.is_available()}) if torch.cuda.is_available(): print(fGPU设备: {torch.cuda.get_device_name(0)})2.3 数据集准备计算机视觉项目需要大量的图像数据。常用的公开数据集包括MNIST手写数字识别CIFAR-10/100物体分类ImageNet大规模图像分类COCO目标检测和分割3. CNN卷积神经网络详解3.1 卷积操作基本原理卷积是CNN的核心操作它通过滑动窗口的方式在图像上提取特征。每个卷积核负责检测一种特定的特征模式如边缘、纹理等。import torch import torch.nn as nn import torch.nn.functional as F # 简单的卷积操作示例 class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() # 输入通道1输出通道32卷积核3x3 self.conv1 nn.Conv2d(1, 32, 3, padding1) self.conv2 nn.Conv2d(32, 64, 3, padding1) self.pool nn.MaxPool2d(2, 2) self.fc1 nn.Linear(64 * 7 * 7, 128) self.fc2 nn.Linear(128, 10) def forward(self, x): x self.pool(F.relu(self.conv1(x))) # 28x28 - 14x14 x self.pool(F.relu(self.conv2(x))) # 14x14 - 7x7 x x.view(-1, 64 * 7 * 7) # 展平 x F.relu(self.fc1(x)) x self.fc2(x) return x # 测试网络 model SimpleCNN() print(model)3.2 池化层与激活函数池化层主要用于降维和保持平移不变性常见的池化操作包括最大池化和平均池化。激活函数引入非线性使网络能够学习复杂模式ReLU是目前最常用的激活函数。3.3 经典CNN架构分析LeNet-5是早期的CNN成功案例用于手写数字识别。AlexNet首次在现代GPU上成功训练深度网络VGGNet通过使用小卷积核堆叠深层次网络GoogleNet引入Inception模块提高参数效率。# VGG风格网络实现 class VGGStyle(nn.Module): def __init__(self, num_classes10): super(VGGStyle, self).__init__() self.features nn.Sequential( # 第一个卷积块 nn.Conv2d(3, 64, 3, padding1), nn.ReLU(inplaceTrue), nn.Conv2d(64, 64, 3, padding1), nn.ReLU(inplaceTrue), nn.MaxPool2d(2, 2), # 第二个卷积块 nn.Conv2d(64, 128, 3, padding1), nn.ReLU(inplaceTrue), nn.Conv2d(128, 128, 3, padding1), nn.ReLU(inplaceTrue), nn.MaxPool2d(2, 2), ) self.classifier nn.Sequential( nn.Linear(128 * 8 * 8, 512), nn.ReLU(inplaceTrue), nn.Dropout(0.5), nn.Linear(512, num_classes) ) def forward(self, x): x self.features(x) x x.view(x.size(0), -1) x self.classifier(x) return x4. ResNet残差网络与迁移学习4.1 残差连接原理随着网络深度增加梯度消失和梯度爆炸问题变得严重。ResNet通过引入残差连接skip connection解决了深层网络训练困难的问题。残差块的基本思想是学习输入与输出之间的残差差值而不是直接学习目标映射。这样即使深层网络的权重很小信息也能通过快捷连接直接传递。4.2 ResNet架构实现import torch import torch.nn as nn class BasicBlock(nn.Module): expansion 1 def __init__(self, in_planes, planes, stride1): super(BasicBlock, self).__init__() self.conv1 nn.Conv2d(in_planes, planes, kernel_size3, stridestride, padding1, biasFalse) self.bn1 nn.BatchNorm2d(planes) self.conv2 nn.Conv2d(planes, planes, kernel_size3, stride1, padding1, biasFalse) self.bn2 nn.BatchNorm2d(planes) self.shortcut nn.Sequential() if stride ! 1 or in_planes ! self.expansion * planes: self.shortcut nn.Sequential( nn.Conv2d(in_planes, self.expansion * planes, kernel_size1, stridestride, biasFalse), nn.BatchNorm2d(self.expansion * planes) ) def forward(self, x): out F.relu(self.bn1(self.conv1(x))) out self.bn2(self.conv2(out)) out self.shortcut(x) # 残差连接 out F.relu(out) return out class ResNet(nn.Module): def __init__(self, block, num_blocks, num_classes10): super(ResNet, self).__init__() self.in_planes 64 self.conv1 nn.Conv2d(3, 64, kernel_size3, stride1, padding1, biasFalse) self.bn1 nn.BatchNorm2d(64) self.layer1 self._make_layer(block, 64, num_blocks[0], stride1) self.layer2 self._make_layer(block, 128, num_blocks[1], stride2) self.layer3 self._make_layer(block, 256, num_blocks[2], stride2) self.layer4 self._make_layer(block, 512, num_blocks[3], stride2) self.linear nn.Linear(512 * block.expansion, num_classes) def _make_layer(self, block, planes, num_blocks, stride): strides [stride] [1] * (num_blocks - 1) layers [] for stride in strides: layers.append(block(self.in_planes, planes, stride)) self.in_planes planes * block.expansion return nn.Sequential(*layers) def forward(self, x): out F.relu(self.bn1(self.conv1(x))) out self.layer1(out) out self.layer2(out) out self.layer3(out) out self.layer4(out) out F.avg_pool2d(out, 4) out out.view(out.size(0), -1) out self.linear(out) return out def ResNet18(): return ResNet(BasicBlock, [2, 2, 2, 2])4.3 迁移学习实战迁移学习允许我们利用在大型数据集上预训练的模型将其知识迁移到新的任务中。这种方法特别适合数据量较小的场景。import torchvision.models as models import torch.optim as optim from torch.optim import lr_scheduler def setup_transfer_learning(num_classes, feature_extractTrue): # 加载预训练模型 model models.resnet18(pretrainedTrue) if feature_extract: # 冻结所有参数 for param in model.parameters(): param.requires_grad False # 修改最后一层全连接层 num_features model.fc.in_features model.fc nn.Linear(num_features, num_classes) return model # 训练函数 def train_model(model, dataloaders, criterion, optimizer, scheduler, num_epochs25): best_model_wts copy.deepcopy(model.state_dict()) best_acc 0.0 for epoch in range(num_epochs): print(fEpoch {epoch}/{num_epochs - 1}) print(- * 10) # 每个epoch都有训练和验证阶段 for phase in [train, val]: if phase train: model.train() # 训练模式 else: model.eval() # 评估模式 running_loss 0.0 running_corrects 0 # 迭代数据 for inputs, labels in dataloaders[phase]: inputs inputs.to(device) labels labels.to(device) # 梯度清零 optimizer.zero_grad() # 前向传播 with torch.set_grad_enabled(phase train): outputs model(inputs) _, preds torch.max(outputs, 1) loss criterion(outputs, labels) # 反向传播优化只在训练阶段进行 if phase train: loss.backward() optimizer.step() # 统计 running_loss loss.item() * inputs.size(0) running_corrects torch.sum(preds labels.data) if phase train: scheduler.step() epoch_loss running_loss / len(dataloaders[phase].dataset) epoch_acc running_corrects.double() / len(dataloaders[phase].dataset) print(f{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}) # 深度拷贝模型 if phase val and epoch_acc best_acc: best_acc epoch_acc best_model_wts copy.deepcopy(model.state_dict()) print() # 加载最佳模型权重 model.load_state_dict(best_model_wts) return model5. U-Net图像分割网络5.1 U-Net架构原理U-Net是医学图像分割领域的经典网络采用编码器-解码器结构通过跳跃连接将底层细节信息与高层语义信息融合。编码器部分通过卷积和池化逐步提取特征减少空间维度同时增加通道数。解码器部分通过上采样恢复空间分辨率跳跃连接帮助保留细节信息。5.2 U-Net完整实现import torch import torch.nn as nn class DoubleConv(nn.Module): (卷积 [BN] ReLU) * 2 def __init__(self, in_channels, out_channels): super().__init__() self.double_conv nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue), nn.Conv2d(out_channels, out_channels, kernel_size3, padding1), nn.BatchNorm2d(out_channels), nn.ReLU(inplaceTrue) ) def forward(self, x): return self.double_conv(x) class Down(nn.Module): 下采样模块最大池化 双卷积 def __init__(self, in_channels, out_channels): super().__init__() self.maxpool_conv nn.Sequential( nn.MaxPool2d(2), DoubleConv(in_channels, out_channels) ) def forward(self, x): return self.maxpool_conv(x) class Up(nn.Module): 上采样模块 def __init__(self, in_channels, out_channels, bilinearTrue): super().__init__() if bilinear: self.up nn.Upsample(scale_factor2, modebilinear, align_cornersTrue) self.conv DoubleConv(in_channels, out_channels) else: self.up nn.ConvTranspose2d(in_channels, in_channels // 2, kernel_size2, stride2) self.conv DoubleConv(in_channels, out_channels) def forward(self, x1, x2): x1 self.up(x1) # 输入是CHW diffY x2.size()[2] - x1.size()[2] diffX x2.size()[3] - x1.size()[3] x1 F.pad(x1, [diffX // 2, diffX - diffX // 2, diffY // 2, diffY - diffY // 2]) x torch.cat([x2, x1], dim1) return self.conv(x) class OutConv(nn.Module): def __init__(self, in_channels, out_channels): super(OutConv, self).__init__() self.conv nn.Conv2d(in_channels, out_channels, kernel_size1) def forward(self, x): return self.conv(x) class UNet(nn.Module): def __init__(self, n_channels, n_classes, bilinearTrue): super(UNet, self).__init__() self.n_channels n_channels self.n_classes n_classes self.bilinear bilinear self.inc DoubleConv(n_channels, 64) self.down1 Down(64, 128) self.down2 Down(128, 256) self.down3 Down(256, 512) factor 2 if bilinear else 1 self.down4 Down(512, 1024 // factor) self.up1 Up(1024, 512 // factor, bilinear) self.up2 Up(512, 256 // factor, bilinear) self.up3 Up(256, 128 // factor, bilinear) self.up4 Up(128, 64, bilinear) self.outc OutConv(64, n_classes) def forward(self, x): x1 self.inc(x) x2 self.down1(x1) x3 self.down2(x2) x4 self.down3(x3) x5 self.down4(x4) x self.up1(x5, x4) x self.up2(x, x3) x self.up3(x, x2) x self.up4(x, x1) logits self.outc(x) return logits # 使用示例 model UNet(n_channels3, n_classes1) print(f模型参数量: {sum(p.numel() for p in model.parameters())})5.3 医学图像分割实战U-Net在医学影像分割中表现优异下面展示一个细胞核分割的完整流程import numpy as np from torch.utils.data import Dataset, DataLoader from sklearn.model_selection import train_test_split class MedicalDataset(Dataset): def __init__(self, images, masks, transformNone): self.images images self.masks masks self.transform transform def __len__(self): return len(self.images) def __getitem__(self, idx): image self.images[idx] mask self.masks[idx] if self.transform: augmented self.transform(imageimage, maskmask) image augmented[image] mask augmented[mask] return image, mask def train_unet(): # 数据准备 # 这里假设已经有预处理好的图像和掩码数据 # images, masks load_medical_data() # 分割训练集和测试集 # train_images, val_images, train_masks, val_masks train_test_split( # images, masks, test_size0.2, random_state42) # 创建数据集和数据加载器 # train_dataset MedicalDataset(train_images, train_masks, transformtrain_transform) # val_dataset MedicalDataset(val_images, val_masks, transformval_transform) # train_loader DataLoader(train_dataset, batch_size8, shuffleTrue) # val_loader DataLoader(val_dataset, batch_size8, shuffleFalse) model UNet(n_channels3, n_classes1) criterion nn.BCEWithLogitsLoss() optimizer torch.optim.Adam(model.parameters(), lr1e-4) # 训练循环 for epoch in range(100): model.train() epoch_loss 0 for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output model(data) loss criterion(output, target) loss.backward() optimizer.step() epoch_loss loss.item() # 验证阶段 model.eval() val_loss 0 with torch.no_grad(): for data, target in val_loader: output model(data) val_loss criterion(output, target).item() print(fEpoch {epoch}, Train Loss: {epoch_loss/len(train_loader):.4f}, fVal Loss: {val_loss/len(val_loader):.4f})6. Transformer在计算机视觉中的应用6.1 Vision Transformer原理Vision Transformer将图像分割成固定大小的patch将每个patch线性映射为向量序列然后输入到标准的Transformer编码器中。这种架构能够捕捉长距离依赖关系在图像分类任务中表现出色。import torch import torch.nn as nn import math class PatchEmbedding(nn.Module): 将图像分割成patch并嵌入 def __init__(self, img_size224, patch_size16, in_chans3, embed_dim768): super().__init__() self.img_size img_size self.patch_size patch_size self.n_patches (img_size // patch_size) ** 2 self.proj nn.Conv2d(in_chans, embed_dim, kernel_sizepatch_size, stridepatch_size) def forward(self, x): x self.proj(x) # (B, E, H/P, W/P) x x.flatten(2) # (B, E, N) x x.transpose(1, 2) # (B, N, E) return x class MultiHeadAttention(nn.Module): 多头自注意力机制 def __init__(self, dim, num_heads8, qkv_biasFalse, attn_drop0., proj_drop0.): super().__init__() self.num_heads num_heads head_dim dim // num_heads self.scale head_dim ** -0.5 self.qkv nn.Linear(dim, dim * 3, biasqkv_bias) self.attn_drop nn.Dropout(attn_drop) self.proj nn.Linear(dim, dim) self.proj_drop nn.Dropout(proj_drop) def forward(self, x): B, N, C x.shape qkv self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) q, k, v qkv[0], qkv[1], qkv[2] attn (q k.transpose(-2, -1)) * self.scale attn attn.softmax(dim-1) attn self.attn_drop(attn) x (attn v).transpose(1, 2).reshape(B, N, C) x self.proj(x) x self.proj_drop(x) return x class MLP(nn.Module): 多层感知机 def __init__(self, in_features, hidden_featuresNone, out_featuresNone, drop0.): super().__init__() out_features out_features or in_features hidden_features hidden_features or in_features self.fc1 nn.Linear(in_features, hidden_features) self.act nn.GELU() self.fc2 nn.Linear(hidden_features, out_features) self.drop nn.Dropout(drop) def forward(self, x): x self.fc1(x) x self.act(x) x self.drop(x) x self.fc2(x) x self.drop(x) return x class TransformerBlock(nn.Module): Transformer块 def __init__(self, dim, num_heads, mlp_ratio4., qkv_biasFalse, drop0., attn_drop0.): super().__init__() self.norm1 nn.LayerNorm(dim) self.attn MultiHeadAttention(dim, num_headsnum_heads, qkv_biasqkv_bias, attn_dropattn_drop, proj_dropdrop) self.norm2 nn.LayerNorm(dim) mlp_hidden_dim int(dim * mlp_ratio) self.mlp MLP(in_featuresdim, hidden_featuresmlp_hidden_dim, dropdrop) def forward(self, x): x x self.attn(self.norm1(x)) x x self.mlp(self.norm2(x)) return x class VisionTransformer(nn.Module): 完整的Vision Transformer模型 def __init__(self, img_size224, patch_size16, in_chans3, num_classes1000, embed_dim768, depth12, num_heads12, mlp_ratio4., qkv_biasTrue, drop_rate0., attn_drop_rate0.): super().__init__() self.num_classes num_classes self.num_features self.embed_dim embed_dim self.patch_embed PatchEmbedding(img_size, patch_size, in_chans, embed_dim) num_patches self.patch_embed.n_patches self.cls_token nn.Parameter(torch.zeros(1, 1, embed_dim)) self.pos_embed nn.Parameter(torch.zeros(1, num_patches 1, embed_dim)) self.pos_drop nn.Dropout(pdrop_rate) self.blocks nn.ModuleList([ TransformerBlock(dimembed_dim, num_headsnum_heads, mlp_ratiomlp_ratio, qkv_biasqkv_bias, dropdrop_rate, attn_dropattn_drop_rate) for i in range(depth)]) self.norm nn.LayerNorm(embed_dim) self.head nn.Linear(embed_dim, num_classes) if num_classes 0 else nn.Identity() # 初始化权重 nn.init.trunc_normal_(self.pos_embed, std0.02) nn.init.trunc_normal_(self.cls_token, std0.02) self.apply(self._init_weights) def _init_weights(self, m): if isinstance(m, nn.Linear): nn.init.trunc_normal_(m.weight, std0.02) if m.bias is not None: nn.init.constant_(m.bias, 0) elif isinstance(m, nn.LayerNorm): nn.init.constant_(m.bias, 0) nn.init.constant_(m.weight, 1.0) def forward(self, x): B x.shape[0] x self.patch_embed(x) cls_tokens self.cls_token.expand(B, -1, -1) x torch.cat((cls_tokens, x), dim1) x x self.pos_embed x self.pos_drop(x) for blk in self.blocks: x blk(x) x self.norm(x) x x[:, 0] # 取cls token对应的输出 x self.head(x) return x # 使用示例 vit VisionTransformer(img_size224, patch_size16, num_classes10, embed_dim768, depth12, num_heads12) print(fViT参数量: {sum(p.numel() for p in vit.parameters())})6.2 Swin Transformer架构Swin Transformer通过引入分层设计和滑动窗口注意力解决了ViT计算复杂度高和缺乏平移不变性的问题在各类视觉任务中表现出色。class SwinTransformerBlock(nn.Module): Swin Transformer块 def __init__(self, dim, input_resolution, num_heads, window_size7, shift_size0): super().__init__() self.dim dim self.input_resolution input_resolution self.num_heads num_heads self.window_size window_size self.shift_size shift_size if min(self.input_resolution) self.window_size: self.shift_size 0 self.window_size min(self.input_resolution) self.attn WindowAttention(dim, window_size, num_heads) self.norm1 nn.LayerNorm(dim) self.mlp MLP(dim, int(dim * 4)) self.norm2 nn.LayerNorm(dim) def forward(self, x): H, W self.input_resolution B, L, C x.shape shortcut x x self.norm1(x) x x.view(B, H, W, C) # 滑动窗口分割 if self.shift_size 0: shifted_x torch.roll(x, shifts(-self.shift_size, -self.shift_size), dims(1, 2)) else: shifted_x x # 窗口注意力 x_windows window_partition(shifted_x, self.window_size) attn_windows self.attn(x_windows) shifted_x window_reverse(attn_windows, self.window_size, H, W) if self.shift_size 0: x torch.roll(shifted_x, shifts(self.shift_size, self.shift_size), dims(1, 2)) else: x shifted_x x x.view(B, H * W, C) x shortcut x # MLP x x self.mlp(self.norm2(x)) return x7. 混合架构与最新进展7.1 ConvNeXt与ACC-UNetConvNeXt通过将现代Transformer的设计理念应用到CNN中证明了纯卷积网络仍然具有竞争力。ACC-UNet在此基础上进一步优化在医学图像分割任务中超越了基于Transformer的模型。class ACCUNetBlock(nn.Module): ACC-UNet中的改进卷积块 def __init__(self, in_channels, out_channels, k3): super().__init__() # 倒残差结构 self.conv1 nn.Conv2d(in_channels, out_channels * 4, 1) self.dwconv nn.Conv2d(out_channels * 4, out_channels * 4, k, paddingk//2, groupsout_channels * 4) self.conv2 nn.Conv2d(out_channels * 4, out_channels, 1) self.norm nn.BatchNorm2d(out_channels) self.act nn.GELU() def forward(self, x): identity x # 倒残差结构 x self.conv1(x) x self.dwconv(x) x self.conv2(x) x self.norm(x) x self.act(x) # 残差连接 if identity.shape x.shape: x x identity return x7.2 模型选择指南在选择计算机视觉模型时需要考虑多个因素数据量大小小数据集适合使用预训练模型进行迁移学习大数据集可以训练更复杂的模型。计算资源Transformer模型通常需要更多计算资源CNN在资源受限环境下更有优势。任务类型分类任务ViT表现优异分割任务U-Net系列仍是首选检测任务YOLO、Faster R-CNN等各具特色。实时性要求移动端部署需要考虑模型大小和推理速度轻量级CNN架构更适合。8. 实战项目综合图像处理系统8.1 项目架构设计下面实现一个综合的图像处理系统集成分类、检测和分割功能import torch import torch.nn as nn from torchvision import transforms from PIL import Image import cv2 import numpy as np class ComprehensiveVisionSystem: def __init__(self): # 初始化各任务模型 self.classification_model self.load_classification_model() self.detection_model self.load_detection_model() self.segmentation_model self.load_segmentation_model() self.transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) def load_classification_model(self): 加载图像分类模型 model models.resnet50(pretrainedTrue) model.eval() return model def load_detection_model(self): 加载目标检测模型 # 这里可以使用YOLO、Faster R-CNN等 model torch.hub.load(ultralytics/yolov5, yolov5s, pretrainedTrue) return model def load_segmentation_model(self): 加载图像分割模型 model UNet(n_channels3, n_classes21) # 假设21个类别 # 加载预训练权重 # model.load_state_dict(torch.load(unet_weights.pth)) model.eval() return model def classify_image(self, image_path): 图像分类 image Image.open(image_path).convert(RGB) input_tensor self.transform(image).unsqueeze(0) with torch.no_grad(): output self.classification_model(input_tensor) probabilities torch.nn.functional.softmax(output[0], dim0) # 获取top-5预测结果 top5_prob, top5_catid torch.topk(probabilities, 5) return top5_prob, top5_catid def detect_objects(self, image_path): 目标检测 results self.detection_model(image_path) return results.pandas().xyxy[0] # 返回检测结果 def segment_image(self, image_path): 图像分割 image Image.open(image_path).convert(RGB) original_size image.size # 预处理 image_tensor self.transform(image).unsqueeze(0) with torch.no_grad(): output self.segmentation_model(image_tensor) mask torch.argmax(output, dim1).squeeze().cpu().numpy() # 将mask调整回原图大小 mask cv2.resize(mask, original_size, interpolationcv2.INTER_NEAREST) return mask def process_comprehensive(self, image_path): 综合处理分类检测分割 print(开始综合图像分析...) # 分类 print(1. 图像分类分析:) probs