《Pytorch深度学习和图神经网络(卷 2)》学习笔记——第二章

基于图片内容的处理任务

主要包括目标检测、图片分割两大任务。
目标检测:精度相对较高,主要是以检测框的方式,找出图片中目标物体所在坐标。模型运算量相对较小,相对较快。
图片分割:精度相对较低,主要是以像素点的集合方式,找出图片中目标物体边缘的具体像素点。模型运算量相对较大,相对较慢。

目标检测

单阶段:也叫Region-free方法,直接从模型获得预测结果,有YOLO、SSD、RetinaNet等。
两阶段:先检测包含实物的区域,再对该区域内的实物进行分类识别。有R-CNN、Faster R-CNN、Mask R-CNN等。
两阶段检测模型在检测框方面表现的精度更高,单阶段在分类方面表现出的精度更高。

图片分割

语义分割:能将图片中具有不同语义的部分分开
实例分割:能描述出目标物体的轮廓(比检测框更为精细),比语义分割还能识别出单个的具体个体。

非极大值抑制算法(Non-Max Suppression)

目标检测中,会检测出很多个结果,可能会出现重复物体(中心和大小略有不同),要用NMS对检测结果进行去重。具体过程如下:
从所有的检测框中找到置信度较大(大于某个阈值)的检测框
逐一计算其与剩余检测框的区域面积重叠率(IOU)
如果IOU大于一定阈值则剔除
重复上述过程
IOU(Intersection Over Union)交并比

Mask R-CNN 模型

属于两阶段模型,具体步骤如下:
用NMS将一张图分成多个子框,称作锚点,不同尺寸存在重叠。
在图片中为具体实物标注坐标。
根据坐标和IOU计算那些锚点是前景(IOU高的),哪些是背景(IOU低的)。
计算前景的锚点坐标和实物标注的坐标,计算二者的相对位移和长宽的缩放比例。
最终检测区域会转换为一堆锚点的分类(前景和背景)和回归任务(偏移和缩放),每张图片会将其自身标注的信息转化为锚点对应的标签,让模型对已有的锚点进行训练或识别。
在模型中实现区域检测功能的网络被称作区域生成网络(Region Proposal Network),实际处理中会从RPN的输出结果中选取前景概率较高的一定数量的锚点作为感兴趣区域(Region Of Interest),送到第二阶段的网络中进行计算。

完整步骤:
提取主特征:又称作骨干网络,从图片中提取出一些不同尺寸的特征,通常用一些预训练好的模型(VGG、Inception、ResNet等),这些获得的特征数据被称作特征图。
特征融合:用特征融合金字塔(Feature Pyramin Network)整合骨干网络中的不同尺寸,最终的特征信息用于后面的RPN和最终的分类器网络的计算。
提取ROI:主要通过RPN来实现,在众多锚点计算前景背景的预测值,基于锚点的便宜,然后对前景概率较大的ROI用NMS去重,最终结果取出指定个数的ROI用于后续的计算。
ROI池化:用区域对齐(ROI Align)的方式实现,将特征融合的结果当做图片,按照ROI中的区域框位置从图中取出对应内容,将形状统一成指定大小,用于后面的计算。
最终检测:对上一步的结果一次进行分类,设置矩形坐标、实物像素分割处理。得到最终结果。

实例:使用Mask R-CNN模型进行目标检测与语义分割

cv2.error: OpenCV(4.8.0) 👎 error: (-5:Bad argument)

in function ‘putText’
Overload resolution failed:
Can’t parse ‘org’. Sequence item with index 0 has a wrong type

in function ‘rectangle’
Overload resolution failed:
Can’t parse ‘pt1’. Sequence item with index 0 has a wrong type
argument for rectangle() given by name (‘color’) and position (3)
上述两种报错是因为这两个函数坐标只能是int类型
cv2.rectangle()
cv2.putText()

可以用这种方式对元组里的数据强制类型转换

# initializing list
test_list = [(4, 5), (6, 7), (1, 4), (8, 10)]
  
# printing original list
print("The original list is : " + str(test_list))
  
# Change Datatype of Tuple Values
# Using enumerate() + loop
# converting to string using str()
for idx, (x, y) in enumerate(test_list):
    test_list[idx] = (x, str(y))
  
# printing result 
print("The converted records : " + str(test_list)) 

完整代码:

from PIL import Image
import matplotlib.pyplot as plt
import torchvision.transforms as T
import torchvision
import numpy as np
import cv2
import random
import torch

#加载模型
model = torchvision.models.detection.maskrcnn_resnet50_fpn()
model.load_state_dict(torch.load(r"pytorch\2-chapter1\some3\maskrcnn_resnet50_fpn_coco-bf2d0c1e.pth")) 	#true 代表下载
model = model.eval()
model.eval()

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

def get_prediction(img_path, threshold):
  img = Image.open(img_path)
  transform = T.Compose([T.ToTensor()])
  img = transform(img)
  pred = model([img])
  print('pred')
  print(pred)
  pred_score = list(pred[0]['scores'].detach().numpy())
  pred_t = [pred_score.index(x) for x in pred_score if x>threshold][-1]
  print("masks>0.5")
  print(pred[0]['masks']>0.5)
  masks = (pred[0]['masks']>0.5).squeeze().detach().cpu().numpy()
  print("this is masks")
  print(masks)
  pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i] for i in list(pred[0]['labels'].numpy())]
  pred_boxes = [[(i[0], i[1]), (i[2], i[3])] for i in list(pred[0]['boxes'].detach().numpy())]
  masks = masks[:pred_t+1]
  pred_boxes = pred_boxes[:pred_t+1]
  pred_class = pred_class[:pred_t+1]
  return masks, pred_boxes, pred_class


def random_colour_masks(image):
  colours = [[0, 255, 0],[0, 0, 255],[255, 0, 0],[0, 255, 255],[255, 255, 0],[255, 0, 255],[80, 70, 180],[250, 80, 190],[245, 145, 50],[70, 150, 250],[50, 190, 190]]
  r = np.zeros_like(image).astype(np.uint8)
  g = np.zeros_like(image).astype(np.uint8)
  b = np.zeros_like(image).astype(np.uint8)
  randcol = colours[random.randrange(0,10)]
  r[image == 1] = randcol[0]
  g[image == 1] = randcol[1]
  b[image == 1] = randcol[2]
  coloured_mask = np.stack([r, g, b], axis=2)
  return coloured_mask,randcol

def instance_segmentation_api(img_path, threshold=0.5, rect_th=3, text_size=5, text_th=5):
  masks, boxes, pred_cls = get_prediction(img_path, threshold) #调用模型
  img = cv2.imread(img_path)
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
  for i in range(len(masks)):
    rgb_mask,randcol = random_colour_masks(masks[i])   #为掩码区填充随机值
    img = cv2.addWeighted(img, 1, rgb_mask, 0.5, 0)

    test_list = [boxes[i][0], boxes[i][1]]

    for idx, (x, y) in enumerate(test_list):
        test_list[idx] = (int(x), int(y))
    # print(test_list)

    cv2.rectangle(img, test_list[0], test_list[1],color=randcol, thickness=rect_th)

    test_list = [boxes[i][0]]

    for idx, (x, y) in enumerate(test_list):
        test_list[idx] = (int(x), int(y))
    print(test_list[0])

    # print(img)
    cv2.putText(img,pred_cls[i], test_list[0], cv2.FONT_HERSHEY_SIMPLEX, text_size, randcol,thickness=text_th)
    plt.figure(figsize=(20,30))
  plt.imshow(img)
  plt.xticks([])
  plt.yticks([])
  plt.show()

#显示模型结果
instance_segmentation_api(r'E:\desktop\Home_Code\pytorch\2-chapter1\some1\horse.jpg')

在这里插入图片描述
本书后面的内容与我目前的学习需求关系不大,所以在此结束!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值