YOLOv5 输出目标检测物的坐标信息和类别(可结合flask或者fastapi开发成目标检测接口)
直接上代码
import io
import numpy as np
import cv2
import torch
from PIL import Image
from numpy import random
'''
代码:由YOLOv5自带的detect.py 改编
实现:输入图片进行检测,输出图片的类别和坐标和对应的分数
autor:小帆芽芽
date:2021/12/21
'''
from YOLO.models.experimental import attempt_load
from YOLO.utils.general import check_img_size, non_max_suppression, scale_coords, \
set_logging
from YOLO.utils.torch_utils import select_device, time_synchronized
def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True):
shape = img.shape[:2]
if isinstance(new_shape, int):
new_shape = (new_shape, new_shape)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
if not scaleup:
r = min(r, 1.0)
ratio = r, r
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]
if auto:
dw, dh = np.mod(dw, 32), np.mod(dh, 32)
elif scaleFill:
dw, dh = 0.0, 0.0
new_unpad = (new_shape[1], new_shape[0])
ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]
dw /= 2
dh /= 2
if shape[::-1] != new_unpad:
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
return img, ratio, (dw, dh)
weights = 'YOLO/weights/best.pt'
opt_device = ''
imgsz = 640
opt_conf_thres = 0.25
opt_iou_thres = 0.5
set_logging()
device = select_device(opt_device)
half = device.type != 'cpu'
model = attempt_load(weights, map_location=device)
imgsz = check_img_size(imgsz, s=model.stride.max())
if half:
model.half()
names = model.module.names if hasattr(model, 'module') else model.names
colors = [[random.randint(0, 255) for _ in range(3)] for _ in names]
def bytes_img(image_bytes):
img = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
return rgb_img
def predict_(pic_):
img = torch.zeros((1, 3, imgsz, imgsz), device=device)
_ = model(img.half() if half else img) if device.type != 'cpu' else None
im0s = pic_
img = letterbox(im0s, new_shape=imgsz)[0]
img = img[:, :, ::-1].transpose(2, 0, 1)
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).to(device)
img = img.half() if half else img.float()
img /= 255.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
pred = model(img)[0]
pred = non_max_suppression(pred, opt_conf_thres, opt_iou_thres)
detect_info = []
for i, det in enumerate(pred):
if len(det):
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0s.shape).round()
for *xyxy, conf, cls in reversed(det):
dic ={
'class':f'{names[int(cls)]}',
'location':torch.tensor(xyxy).view(1, 4).view(-1).tolist(),
'score': round(float(conf) * 100, 2)
}
detect_info.append(dic)
return detect_info