1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| """ 单目深度估计用于 OOP 检测
流程: 1. DMS 摄像头 → RGB 图像 2. 单目深度模型 → 深度图 3. 深度图 + 关键点 → 3D 姿态估计 4. 3D 姿态 → OOP 分类
关键:零额外硬件,仅用现有 DMS 摄像头 """
import torch import torch.nn as nn import numpy as np
class MonoDepthOOPDetector(nn.Module): """ 单目深度估计 → OOP 检测 使用轻量化深度估计模型 输出:深度图 + OOP 分类 """ def __init__(self): super().__init__() self.depth_encoder = nn.Sequential( nn.Conv2d(3, 32, 7, stride=2, padding=3), nn.BatchNorm2d(32), nn.ReLU(), nn.Conv2d(32, 64, 5, stride=2, padding=2), nn.BatchNorm2d(64), nn.ReLU(), nn.Conv2d(64, 128, 3, stride=2, padding=1), nn.BatchNorm2d(128), nn.ReLU(), nn.Conv2d(128, 256, 3, stride=1, padding=1), nn.BatchNorm2d(256), nn.ReLU(), ) self.depth_decoder = nn.Sequential( nn.ConvTranspose2d(256, 128, 3, stride=2, padding=1, output_padding=1), nn.ReLU(), nn.ConvTranspose2d(128, 64, 3, stride=2, padding=1, output_padding=1), nn.ReLU(), nn.ConvTranspose2d(64, 32, 3, stride=2, padding=1, output_padding=1), nn.ReLU(), nn.Conv2d(32, 1, 1), ) self.oop_head = nn.Sequential( nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(256, 128), nn.ReLU(), nn.Dropout(0.2), nn.Linear(128, 6), ) def forward(self, x): feat = self.depth_encoder(x) depth = self.depth_decoder(feat) oop = self.oop_head(feat) return depth, oop
OOP_CLASSES = [ 'normal_sitting', 'leaning_forward', 'leaning_side', 'leaning_back', 'kneeling', 'empty_seat', ]
if __name__ == "__main__": model = MonoDepthOOPDetector() model.eval() x = torch.randn(1, 3, 224, 224) depth, oop = model(x) print(f"输入: {x.shape}") print(f"深度图: {depth.shape}") print(f"OOP 预测: {oop.shape} → {OOP_CLASSES[oop.argmax(1).item()]}") print(f"参数量: {sum(p.numel() for p in model.parameters()):,}")
|