主頁 >  其他 > 【21】使用預訓練的目標檢測與語意分割網路

【21】使用預訓練的目標檢測與語意分割網路

2021-09-19 12:33:46 其他

今天簡單測驗一下pytorch提供的模型

文章目錄

  • 1. 使用訓練好的目標檢測網路
    • 1.1 完整代碼
  • 2. 使用訓練好的語意分割網路
    • 2.1 完整代碼

1. 使用訓練好的目標檢測網路

import numpy as np
import torchvision
import torch
import torchvision.transforms as transforms
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt

加載已經訓練好的ResNet-50-FPN結構的Fast RCNN模型

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)

查看網路結構

# 切換為測驗模式
model.eval()
model.modules
<bound method Module.modules of FasterRCNN(
  (transform): GeneralizedRCNNTransform(
      Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
      Resize(min_size=(800,), max_size=1333, mode='bilinear')
  )
  (backbone): BackboneWithFPN(
    (body): IntermediateLayerGetter(
      (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
      (bn1): FrozenBatchNorm2d(64, eps=0.0)
      (relu): ReLU(inplace=True)
      (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
      (layer1): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=0.0)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=0.0)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (1): FrozenBatchNorm2d(256, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=0.0)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=0.0)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=0.0)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=0.0)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
      (layer2): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(512, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
      (layer3): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(1024, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (4): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (5): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
      (layer4): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=0.0)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=0.0)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(2048, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=0.0)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=0.0)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=0.0)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=0.0)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
    )
    (fpn): FeaturePyramidNetwork(
      (inner_blocks): ModuleList(
        (0): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))
        (1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
        (2): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))
        (3): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1))
      )
      (layer_blocks): ModuleList(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
      (extra_blocks): LastLevelMaxPool()
    )
  )
  (rpn): RegionProposalNetwork(
    (anchor_generator): AnchorGenerator()
    (head): RPNHead(
      (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (cls_logits): Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
      (bbox_pred): Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
    )
  )
  (roi_heads): RoIHeads(
    (box_roi_pool): MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'], output_size=(7, 7), sampling_ratio=2)
    (box_head): TwoMLPHead(
      (fc6): Linear(in_features=12544, out_features=1024, bias=True)
      (fc7): Linear(in_features=1024, out_features=1024, bias=True)
    )
    (box_predictor): FastRCNNPredictor(
      (cls_score): Linear(in_features=1024, out_features=91, bias=True)
      (bbox_pred): Linear(in_features=1024, out_features=364, bias=True)
    )
  )
)>
dataroot = 'E:\學習\機器學習\資料集\VOC2012\VOCdevkit\VOC2012\JPEGImages\\2007_001526.jpg'  # 這是一張五個黑人影像
image = Image.open(dataroot)
# image.show()   # 會彈出影像
transform = transforms.Compose([   # 對影像進行變換
    transforms.ToTensor()
])
image_t = transform(image)   # 格式轉換
image_t.shape
torch.Size([3, 298, 500])
# 一般來說,需要增加維度,第0維度為batchsize
image_t = image_t.unsqueeze(0)
image_t.shape, image.size
(torch.Size([1, 3, 298, 500]), (500, 298))
pred = model(image_t)
pred
[{'boxes': tensor([[377.9250,  13.7037, 493.1622, 297.6194],
          [287.2326,  23.5087, 387.5676, 298.0000],
          [208.0055,  36.3203, 316.6268, 298.0000],
          [ 99.1883,  42.3514, 215.3772, 293.5994],
          [  0.0000,  18.5004, 113.6753, 293.4090],
          [103.1641,  89.9698, 120.0527, 106.6798],
          [377.6761,  83.7355, 389.9832,  99.6203],
          [186.2982,  87.3854, 227.7398, 111.3254],
          [369.1582,  81.4083, 384.1546, 104.8596],
          [104.1660,  80.9660, 192.0679, 223.8538],
          [489.6611,  87.0265, 500.0000, 115.7063],
          [205.3504,  81.7290, 227.3066,  88.7337],
          [ 12.9033,  70.3410, 100.9079, 232.6088],
          [334.8049,  16.4304, 448.6866, 298.0000],
          [  0.0000,  68.2807,  56.2474, 295.7907],
          [359.0639,  79.0281, 378.9404, 104.2661],
          [263.1891,  91.6502, 285.9006, 207.0223],
          [488.7800,  83.5604, 498.6758,  93.8575],
          [397.8902,  69.1296, 475.0887, 158.1689],
          [213.1082,  83.5962, 296.4767, 203.5594],
          [192.5514, 103.8455, 214.0233, 234.5641],
          [108.1454,  83.0643, 165.9468, 166.2449],
          [  2.8212,  71.0566,  42.2922, 203.3171],
          [186.8724,  90.9442, 209.4068, 106.2018],
          [306.5388,  75.2656, 372.6170, 110.4899],
          [312.3708,  70.4173, 364.8932, 133.3953],
          [114.6884,  88.3139, 196.6803, 227.3148],
          [272.4024,  96.7587, 287.4213, 188.5823],
          [264.7156,  95.0346, 280.7938, 172.3812],
          [372.4721, 175.0065, 388.3729, 199.5335],
          [357.0051,  79.2724, 373.7537, 102.6262],
          [ 87.1951,  80.9814, 104.0062, 114.8614],
          [250.1311,  89.9769, 279.9026, 200.7932],
          [206.3279,  81.9413, 227.7696,  88.9331],
          [298.3614,  71.8469, 370.1693, 184.6290],
          [348.6332,  79.9749, 387.5624, 105.4334],
          [ 13.1942,  98.4261, 100.7580, 229.2718],
          [486.5149,  94.5922, 495.3294, 116.6954],
          [185.4654,  85.1627, 228.6101, 112.0963],
          [193.6432, 107.3661, 213.1962, 234.7787],
          [374.9436,  81.5935, 388.6273,  93.4102],
          [369.7113,  81.8386, 386.0195, 105.9965],
          [ 99.3100,  87.0634, 106.2750, 112.2665],
          [194.8513, 108.2166, 212.0829, 232.3898],
          [201.1373,  81.8559, 229.3789,  94.0905],
          [ 19.8349, 185.0172,  90.2345, 237.0425],
          [461.9336,  72.3364, 497.9980, 185.3475],
          [ 90.3956, 112.8333, 111.5753, 243.3585]], grad_fn=<StackBackward>),
  'labels': tensor([ 1,  1,  1,  1,  1,  3,  3,  3,  3, 27,  3,  3, 27,  1,  1,  3, 32,  3,
          27, 27, 27, 27, 27,  3, 27, 27, 31, 32, 32, 31, 27,  3, 32,  8, 27,  3,
          31,  3,  8, 31,  3,  8,  3, 32,  3, 31,  1, 27]),
  'scores': tensor([0.9997, 0.9993, 0.9991, 0.9985, 0.9982, 0.9747, 0.9662, 0.9459, 0.9411,
          0.7976, 0.7688, 0.7279, 0.7057, 0.6844, 0.6773, 0.6273, 0.5956, 0.4991,
          0.4626, 0.3882, 0.3289, 0.3165, 0.2188, 0.1812, 0.1696, 0.1556, 0.1480,
          0.1438, 0.1274, 0.1183, 0.1129, 0.1031, 0.0971, 0.0957, 0.0954, 0.0909,
          0.0851, 0.0842, 0.0730, 0.0724, 0.0651, 0.0647, 0.0623, 0.0598, 0.0563,
          0.0551, 0.0546, 0.0518], grad_fn=<IndexBackward>)}]

這里的輸出包含了3種值,分別是檢測到每個目標的邊界框(boxes)、目標的所屬類別(labels)、以及屬于相應類別的得分(scores),

print(" boxes.shape:{},\n labels.shape:{},\n scores.shape:{}\n".format(pred[0]['boxes'].shape, pred[0]['labels'].shape, pred[0]['scores'].shape))
 boxes.shape:torch.Size([48, 4]),
 labels.shape:torch.Size([48]),
 scores.shape:torch.Size([48])

這張影像可以看出有48個結果輸出,但是只有前9個結果的預測置信度大于90%

# 首先定義每個類別所對應的標簽
COCO_INSTANCE_CATEGORY_NAMES = [
    '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
    'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
    'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
    'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
    'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
    'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
    'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
    'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
    'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
    'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]
len(COCO_INSTANCE_CATEGORY_NAMES)
91

針對上述pred的預測結果,需要提取出有效資料,提取的資訊又每個目標的位置、類別、得分,然后將得分大于0.5的目標作為檢測到的有效目標,并將檢測到的目標在影像上顯示出來

# 使用name2label串列COCO_INSTANCE_CATEGORY_NAMES,提取labels對于的類別名稱
pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())]
# 獲取對應的置信度分數
pred_score = list(pred[0]['scores'].detach().numpy())
# 獲取對應的目標預測檢測框
pred_boxes = [[box[0],box[1],box[2],box[3]] for box in list(pred[0]['boxes'].detach().numpy())]
# 提取置信度大于0.5的結果
pred_index = [pred_score.index(x) for x in pred_score if x > 0.5]
# 獲取到了對應索引:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
# 設定影像顯示字體
fontsize = np.int16(image.size[1]/30)

# 可視化影像.表示在原圖上添加一些元素
draw = ImageDraw.Draw(image)
for index in pred_index:
    # 依次回去邊界框的坐標資訊
    box = pred_boxes[index]
    # 添加矩形框
    draw.rectangle(box, outline="red")
    # 矩陣框中標上: class:score的形式
    texts = pred_class[index] + ":" + str(np.round(pred_score[index], 4))
#     texts = pred_class[index] + ":" + str(format(pred_score[index], '.4f'))
    # 在影像上的指定位置添加文本
    draw.text((box[0], box[1]), texts, fill="red")
    
image

在這里插入圖片描述

1.1 完整代碼

import numpy as np
import torchvision
import torch
import torchvision.transforms as transforms
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt


# 首先定義每個類別所對應的標簽
COCO_INSTANCE_CATEGORY_NAMES = [
    '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
    'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
    'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
    'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
    'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
    'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
    'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
    'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
    'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
    'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]

# 現在將其包裝成一個函式
def Object_Dection(model, imagepath, COCO_INSTANCE_CATEGORY_NAMES):
    # 打卡影像
    image = Image.open(imagepath)
    # image.show()   # 會彈出影像
    transform = transforms.Compose([  # 對影像進行變換
        transforms.ToTensor()
    ])
    image_t = transform(image)  # 格式轉換

    # 增維
    image_t = image_t.unsqueeze(0)
    pred = model(image_t)

    # 使用name2label串列COCO_INSTANCE_CATEGORY_NAMES,提取labels對于的類別名稱
    pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())]
    # 獲取對應的置信度分數
    pred_score = list(pred[0]['scores'].detach().numpy())
    # 獲取對應的目標預測檢測框
    pred_boxes = [[box[0], box[1], box[2], box[3]] for box in list(pred[0]['boxes'].detach().numpy())]
    # 提取置信度大于0.8的結果
    pred_index = [pred_score.index(x) for x in pred_score if x > 0.8]

    # 設定影像顯示字體
    #     fontsize = np.int16(image.size[1]/30)
    #     font = ImageFont.truetype("/Library/Fonts/華文細黑.ttf", fontsize)

    # 在原圖上添加資訊
    draw = ImageDraw.Draw(image)
    for index in pred_index:
        # 依次回去邊界框的坐標資訊
        box = pred_boxes[index]
        # 添加矩形框
        draw.rectangle(box, outline="red", width=3)
        # 矩陣框中標上: class:score的形式
        texts = pred_class[index] + ":" + str(np.round(pred_score[index], 4))
        #     texts = pred_class[index] + ":" + str(format(pred_score[index], '.4f'))
        # 在影像上的指定位置添加文本
        draw.text((box[0], box[1]), texts, fill="red")

    return image

# 測驗
if __name__ == '__main__':

    # 加載模型
    model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)

    # 切換為測驗模式
    model.eval()

    imagepath =  'E:\學習\機器學習\資料集\VOC2012\VOCdevkit\VOC2012\JPEGImages\\2007_001526.jpg'
    image = Object_Dection(model, imagepath, COCO_INSTANCE_CATEGORY_NAMES)

    # 顯示影像
    image.show()

結果展示:

在這里插入圖片描述

2. 使用訓練好的語意分割網路

# 加載模型
model = torchvision.models.segmentation.fcn_resnet101(pretrained=True)
model.eval()

imagepath = 'E:\學習\機器學習\資料集\VOC2012\VOCdevkit\VOC2012\JPEGImages\\2007_001526.jpg'
image = Image.open(imagepath)

# 對影像進行變換
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                         std=[0.229, 0.224, 0.225])
])
image_t = transform(image)
image_t = image_t.unsqueeze(0)
pred = model(image_t)
image_t.shape
torch.Size([1, 3, 298, 500])
pred
OrderedDict([('out',
              tensor([[[[10.7415, 10.7415, 10.7415,  ...,  9.5000,  9.5000,  9.5000],
                        [10.7415, 10.7415, 10.7415,  ...,  9.5000,  9.5000,  9.5000],
                        [10.7415, 10.7415, 10.7415,  ...,  9.5000,  9.5000,  9.5000],
                        ...,
                        [ 7.4524,  7.4524,  7.4524,  ...,  9.5723,  9.5723,  9.5723],
                        [ 7.4524,  7.4524,  7.4524,  ...,  9.5723,  9.5723,  9.5723],
                        [ 7.4524,  7.4524,  7.4524,  ...,  9.5723,  9.5723,  9.5723]],
              
                       [[-1.6881, -1.6881, -1.6881,  ..., -0.0993, -0.0993, -0.0993],
                        [-1.6881, -1.6881, -1.6881,  ..., -0.0993, -0.0993, -0.0993],
                        [-1.6881, -1.6881, -1.6881,  ..., -0.0993, -0.0993, -0.0993],
                        ...,
                        [-1.4228, -1.4228, -1.4228,  ..., -0.1377, -0.1377, -0.1377],
                        [-1.4228, -1.4228, -1.4228,  ..., -0.1377, -0.1377, -0.1377],
                        [-1.4228, -1.4228, -1.4228,  ..., -0.1377, -0.1377, -0.1377]],
              
                       [[-2.3719, -2.3719, -2.3719,  ..., -1.8977, -1.8977, -1.8977],
                        [-2.3719, -2.3719, -2.3719,  ..., -1.8977, -1.8977, -1.8977],
                        [-2.3719, -2.3719, -2.3719,  ..., -1.8977, -1.8977, -1.8977],
                        ...,
                        [-0.8262, -0.8262, -0.8262,  ..., -1.6540, -1.6540, -1.6540],
                        [-0.8262, -0.8262, -0.8262,  ..., -1.6540, -1.6540, -1.6540],
                        [-0.8262, -0.8262, -0.8262,  ..., -1.6540, -1.6540, -1.6540]],
              
                       ...,
              
                       [[-0.5688, -0.5688, -0.5688,  ..., -0.9008, -0.9008, -0.9008],
                        [-0.5688, -0.5688, -0.5688,  ..., -0.9008, -0.9008, -0.9008],
                        [-0.5688, -0.5688, -0.5688,  ..., -0.9008, -0.9008, -0.9008],
                        ...,
                        [ 0.4994,  0.4994,  0.4994,  ...,  1.4651,  1.4651,  1.4651],
                        [ 0.4994,  0.4994,  0.4994,  ...,  1.4651,  1.4651,  1.4651],
                        [ 0.4994,  0.4994,  0.4994,  ...,  1.4651,  1.4651,  1.4651]],
              
                       [[-0.4391, -0.4391, -0.4391,  ...,  2.3527,  2.3527,  2.3527],
                        [-0.4391, -0.4391, -0.4391,  ...,  2.3527,  2.3527,  2.3527],
                        [-0.4391, -0.4391, -0.4391,  ...,  2.3527,  2.3527,  2.3527],
                        ...,
                        [ 0.1844,  0.1844,  0.1844,  ...,  1.2322,  1.2322,  1.2322],
                        [ 0.1844,  0.1844,  0.1844,  ...,  1.2322,  1.2322,  1.2322],
                        [ 0.1844,  0.1844,  0.1844,  ...,  1.2322,  1.2322,  1.2322]],
              
                       [[ 1.3879,  1.3879,  1.3879,  ...,  0.9153,  0.9153,  0.9153],
                        [ 1.3879,  1.3879,  1.3879,  ...,  0.9153,  0.9153,  0.9153],
                        [ 1.3879,  1.3879,  1.3879,  ...,  0.9153,  0.9153,  0.9153],
                        ...,
                        [-0.0281, -0.0281, -0.0281,  ...,  0.4544,  0.4544,  0.4544],
                        [-0.0281, -0.0281, -0.0281,  ...,  0.4544,  0.4544,  0.4544],
                        [-0.0281, -0.0281, -0.0281,  ...,  0.4544,  0.4544,  0.4544]]]],
                     grad_fn=<UpsampleBilinear2DBackward1>)),
             ('aux',
              tensor([[[[ 9.7964,  9.7964,  9.7964,  ...,  8.7053,  8.7053,  8.7053],
                        [ 9.7964,  9.7964,  9.7964,  ...,  8.7053,  8.7053,  8.7053],
                        [ 9.7964,  9.7964,  9.7964,  ...,  8.7053,  8.7053,  8.7053],
                        ...,
                        [ 6.6633,  6.6633,  6.6633,  ...,  8.1096,  8.1096,  8.1096],
                        [ 6.6633,  6.6633,  6.6633,  ...,  8.1096,  8.1096,  8.1096],
                        [ 6.6633,  6.6633,  6.6633,  ...,  8.1096,  8.1096,  8.1096]],
              
                       [[-1.0417, -1.0417, -1.0417,  ..., -0.4245, -0.4245, -0.4245],
                        [-1.0417, -1.0417, -1.0417,  ..., -0.4245, -0.4245, -0.4245],
                        [-1.0417, -1.0417, -1.0417,  ..., -0.4245, -0.4245, -0.4245],
                        ...,
                        [-1.3747, -1.3747, -1.3747,  ..., -0.0461, -0.0461, -0.0461],
                        [-1.3747, -1.3747, -1.3747,  ..., -0.0461, -0.0461, -0.0461],
                        [-1.3747, -1.3747, -1.3747,  ..., -0.0461, -0.0461, -0.0461]],
              
                       [[-1.8145, -1.8145, -1.8145,  ..., -1.1215, -1.1215, -1.1215],
                        [-1.8145, -1.8145, -1.8145,  ..., -1.1215, -1.1215, -1.1215],
                        [-1.8145, -1.8145, -1.8145,  ..., -1.1215, -1.1215, -1.1215],
                        ...,
                        [-0.3710, -0.3710, -0.3710,  ..., -0.8807, -0.8807, -0.8807],
                        [-0.3710, -0.3710, -0.3710,  ..., -0.8807, -0.8807, -0.8807],
                        [-0.3710, -0.3710, -0.3710,  ..., -0.8807, -0.8807, -0.8807]],
              
                       ...,
              
                       [[ 0.6499,  0.6499,  0.6499,  ..., -0.0127, -0.0127, -0.0127],
                        [ 0.6499,  0.6499,  0.6499,  ..., -0.0127, -0.0127, -0.0127],
                        [ 0.6499,  0.6499,  0.6499,  ..., -0.0127, -0.0127, -0.0127],
                        ...,
                        [ 0.6200,  0.6200,  0.6200,  ...,  0.3854,  0.3854,  0.3854],
                        [ 0.6200,  0.6200,  0.6200,  ...,  0.3854,  0.3854,  0.3854],
                        [ 0.6200,  0.6200,  0.6200,  ...,  0.3854,  0.3854,  0.3854]],
              
                       [[-0.6026, -0.6026, -0.6026,  ...,  1.1884,  1.1884,  1.1884],
                        [-0.6026, -0.6026, -0.6026,  ...,  1.1884,  1.1884,  1.1884],
                        [-0.6026, -0.6026, -0.6026,  ...,  1.1884,  1.1884,  1.1884],
                        ...,
                        [-0.8764, -0.8764, -0.8764,  ...,  0.7393,  0.7393,  0.7393],
                        [-0.8764, -0.8764, -0.8764,  ...,  0.7393,  0.7393,  0.7393],
                        [-0.8764, -0.8764, -0.8764,  ...,  0.7393,  0.7393,  0.7393]],
              
                       [[ 1.3283,  1.3283,  1.3283,  ...,  1.2738,  1.2738,  1.2738],
                        [ 1.3283,  1.3283,  1.3283,  ...,  1.2738,  1.2738,  1.2738],
                        [ 1.3283,  1.3283,  1.3283,  ...,  1.2738,  1.2738,  1.2738],
                        ...,
                        [-0.7884, -0.7884, -0.7884,  ..., -0.2274, -0.2274, -0.2274],
                        [-0.7884, -0.7884, -0.7884,  ..., -0.2274, -0.2274, -0.2274],
                        [-0.7884, -0.7884, -0.7884,  ..., -0.2274, -0.2274, -0.2274]]]],
                     grad_fn=<UpsampleBilinear2DBackward1>))])
pred['out'].shape, pred['aux'].shape
(torch.Size([1, 21, 298, 500]), torch.Size([1, 21, 298, 500]))
output = pred['out'].squeeze()
output.shape
torch.Size([21, 298, 500])
# 獲取21類中自信度最高的哪一類,作為像素點的類; 從而實作將3維矩陣變換為二維矩陣
# 現在該二維矩陣中每個取值均代表影像中對應位置像素點的預測類別
outputarg = torch.argmax(output, dim=0).numpy()
outputarg.shape
(298, 500)
# 將像素值的每個預測類別分別編碼為不同的顏色,然后將影像可視化
def decode_segmaps(image, label_colors, nc=21):
    
    # 函式將輸出的2D影像,會將不同類編碼為不同的顏色
    r = np.zeros_like(image).astype(np.uint8)
    g = np.zeros_like(image).astype(np.uint8)
    b = np.zeros_like(image).astype(np.uint8)
    print(r.shape, g.shape, b.shape)  # (298, 500) (298, 500) (298, 500)
    for cls in range(0, nc):
        idx = (image==cls)
        print("cls:{}, idx.shape:{}".format(cls, idx.shape))
        r[idx] = label_colors[cls][0]
        g[idx] = label_colors[cls][1]
        b[idx] = label_colors[cls][2]
    rgbimage = np.stack([r,g,b], axis=2)
    return rgbimage
# 指定顏色編碼
label_colors = np.array([
    (0,0,0),
    (128,0,0),(0,128,0),(128,128,0),(0,0,128),(128,0,128),
    (0,128,128),(128,128,128),(64,0,0),(192,0,0),(64,128,0),
    (192,128,0),(64,0,128),(192,0,128),(64,128,128),(192,128,128),
    (0,64,64),(128,64,0),(0,192,0),(128,192,0),(0,64,128)
])
outputrgb = decode_segmaps(outputarg, label_colors)
outputrgb.shape
(298, 500) (298, 500) (298, 500)

(298, 500, 3)
plt.figure(figsize=(20,8))
plt.subplot(1,1,1)
plt.imshow(outputrgb)
<matplotlib.image.AxesImage at 0x154ee811848>

在這里插入圖片描述

2.1 完整代碼

import numpy as np
import torchvision
import torch
import torchvision.transforms as transforms
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt


# 指定顏色編碼:一共21類,每一類對應一個顏色編碼
label_colors = np.array([
    (0,0,0),
    (128,0,0),(0,128,0),(128,128,0),(0,0,128),(128,0,128),
    (0,128,128),(128,128,128),(64,0,0),(192,0,0),(64,128,0),
    (192,128,0),(64,0,128),(192,0,128),(64,128,128),(192,128,128),
    (0,64,64),(128,64,0),(0,192,0),(128,192,0),(0,64,128)
])


# 將像素值的每個預測類別分別編碼為不同的顏色,然后將影像可視化
def decode_segmaps(image, label_colors, nc=21):

    # 函式將輸出的2D影像,會將不同類編碼為不同的顏色
    r = np.zeros_like(image).astype(np.uint8)
    g = np.zeros_like(image).astype(np.uint8)
    b = np.zeros_like(image).astype(np.uint8)
    # print(r.shape, g.shape, b.shape)  # (298, 500) (298, 500) (298, 500)

    # 回圈遍歷每一層(一共21層),當第cls類出現在image的某些像素值時,這些點索引為idx
    for cls in range(0, nc):
        idx = (image == cls)
        # print("cls:{}, idx.shape:{}".format(cls, idx.shape))

        # 構造rgb三通道:本來是一個類別點變成一個像素(3通道)
        r[idx] = label_colors[cls][0]
        g[idx] = label_colors[cls][1]
        b[idx] = label_colors[cls][2]

    # 三個通道拼接獲取彩色影像
    rgbimage = np.stack([r, g, b], axis=2)

    return rgbimage


# 功能: 輸入影像路徑,輸出分割影像
def Semantic_Segmentation(model, imagepath, label_colors):

    # 獲取圖片
    image = Image.open(imagepath)

    # 對影像進行變換
    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])
    ])
    image_t = transform(image)

    # 增維
    image_t = image_t.unsqueeze(0)
    pred = model(image_t)
    # pred['out'].shape, pred['aux'].shape
    # (torch.Size([1, 21, 298, 500]), torch.Size([1, 21, 298, 500]))

    # 獲取像素點值并降維
    output = pred['out'].squeeze()

    # 獲取21類中自信度最高的哪一類,作為像素點的類; 從而實作將3維矩陣變換為二維矩陣
    # 現在該二維矩陣中每個取值均代表影像中對應位置像素點的預測類別
    outputarg = torch.argmax(output, dim=0).numpy()

    # 類別通道轉換成顏色通道,轉換成一張rgb影像
    outputrgb = decode_segmaps(outputarg, label_colors)

    # 繪制影像
    plt.figure(figsize=(20, 8))
    plt.subplot(1, 1, 1)
    plt.imshow(outputrgb)
    plt.show()


# 測驗
if __name__ == '__main__':

    # 加載模型
    model = torchvision.models.segmentation.fcn_resnet101(pretrained=True)
    model.eval()

    imagepath = 'E:\學習\機器學習\資料集\VOC2012\VOCdevkit\VOC2012\JPEGImages\\2007_001526.jpg'
    Semantic_Segmentation(model, imagepath, label_colors)


結果輸出:
在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301376.html

標籤:其他

上一篇:激光雕刻機裝上AI,混合材料T恤上都能雕出花,自動變換力度保證不割破

下一篇:2021-09-18 稍微寫一些關于RTSP協議分析后的小結

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more