微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从推理 Pytorch 接收坐标

如何解决从推理 Pytorch 接收坐标

我正在尝试获取 Pytorches DefaultPredictor 生成蒙版内像素的坐标,以便稍后获取多边形角并在我的应用程序中使用它。

然而,DefaultPredictor 生成一个 pred_masks 的张量,格式如下:[False,False ... False],... [False,False,.. False] 其中每个单独列表的长度为图像的长度,列表总数为图像的高度。

现在,因为我需要获取掩码内的像素坐标,所以简单的解决方案似乎是循环遍历 pred_masks,检查值和 if == "True" 创建这些元组并将它们添加到列表。但是,当我们谈论宽 x 高约为 3200 x 1600 的图像时,这是一个相对较慢的过程(循环遍历单个 3200x1600 大约需要 4 秒,但因为有相当多的对象需要我进行推断最后 - 这最终会非常慢)。

使用 pytorch (detectron2) 模型获取检测对象的坐标(掩码)的更智能方法是什么?

请在下面找到我的代码以供参考:

from __future__ import print_function

from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.data import MetadataCatalog
from detectron2.data.datasets import register_coco_instances


import cv2
import time


# get image
start = time.time()

im = cv2.imread("inputimage.jpg")

# Create config
cfg = get_cfg()
cfg.merge_from_file("detectron2_repo/configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
cfg.MODEL.ROI_HEADS.score_THRESH_TEST = 0.5 # Set threshold for this model
cfg.MODEL.WEIGHTS = "model_final.pth" # Set path model .pth
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1
cfg.MODEL.DEVICE='cpu'

register_coco_instances("dataset_test",{},"testval.json","Images_path")
test_Metadata = MetadataCatalog.get("dataset_test")


# Create predictor
predictor = DefaultPredictor(cfg)

# Make prediction
outputs = predictor(im)

 
#Loop through the pred_masks and check which ones are equal to TRUE,if equal,add the pixel values to the true_cords_list
outputnump = outputs["instances"].pred_masks.numpy()

true_cords_list = []
x_length = range(len(outputnump[0][0]))
#y kordinaat on range number
for y_cord in range(len(outputnump[0])):
    #x cord
    for x_cord in x_length:
        if str(outputnump[0][y_cord][x_cord]) == "True":
            inputcoords = (x_cord,y_cord)
            true_cords_list.append(inputcoords)

print(str(true_cords_list))

end = time.time()

print(f"Runtime of the program is {end - start}") # 14.29468035697937

//

编辑: 在将 for 循环部分更改为压缩之后 - 我已经设法将 for 循环的运行时间减少了 ~3 倍 - 但是,如果可能的话,理想情况下我希望从预测器本身接收它。

y_length = len(outputnump[0])
x_length = len(outputnump[0][0])
true_cords_list = []
for y_cord in range(y_length):
    x_cords = list(compress(range(x_length),outputnump[0][y_cord]))
    if x_cords:
        for x_cord in x_cords:
            inputcoords = (x_cord,y_cord)
            true_cords_list.append(inputcoords)

解决方法

如果对 NumPy 或 PyTorch 原生数组处理有足够的了解,这个问题很容易解决,与 Python 循环相比,它可以实现 100 倍的加速。您可以研究 NumPy library,PyTorch 张量在行为上与 NumPy 相似。

如何在 NumPy 中获取值的索引

import numpy as np
arr = np.random.rand(3,4) > 0.5
ind = np.argwhere(arr)[:,::-1]
print(arr)
print(ind)

在您的特定情况下,这将是

ind = np.argwhere(outputnump[0])[:,::-1]

如何在 PyTorch 中获取值的索引

import torch
arr = torch.rand(3,4) > 0.5
ind = arr.nonzero()
ind = torch.flip(ind,[1])
print(arr)
print(ind)

[::-1].flip 用于将坐标的顺序从 (y,x) 反转为 (x,y)。

NumPy 和 PyTorch 甚至允许检查简单的条件并获取满足这些条件的值的索引,如需进一步了解,请参阅相应的 NumPy docs article


询问时,您应该提供问题上下文的链接。这个问题实际上是关于 Facebook object detector,他们提供了一个很好的演示 Colab 笔记本。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。