|
|
import os |
|
|
import cv2 |
|
|
import torch |
|
|
import argparse |
|
|
import onnxruntime as ort |
|
|
import numpy as np |
|
|
from lib.core.general import non_max_suppression |
|
|
|
|
|
|
|
|
def resize_unscale(img, new_shape=(640, 640), color=114): |
|
|
shape = img.shape[:2] |
|
|
if isinstance(new_shape, int): |
|
|
new_shape = (new_shape, new_shape) |
|
|
|
|
|
canvas = np.zeros((new_shape[0], new_shape[1], 3)) |
|
|
canvas.fill(color) |
|
|
|
|
|
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) |
|
|
|
|
|
|
|
|
new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) |
|
|
new_unpad_w = new_unpad[0] |
|
|
new_unpad_h = new_unpad[1] |
|
|
pad_w, pad_h = new_shape[1] - new_unpad_w, new_shape[0] - new_unpad_h |
|
|
|
|
|
dw = pad_w // 2 |
|
|
dh = pad_h // 2 |
|
|
|
|
|
if shape[::-1] != new_unpad: |
|
|
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_AREA) |
|
|
|
|
|
canvas[dh:dh + new_unpad_h, dw:dw + new_unpad_w, :] = img |
|
|
|
|
|
return canvas, r, dw, dh, new_unpad_w, new_unpad_h |
|
|
|
|
|
|
|
|
def infer_yolop(weight="yolop-640-640.onnx", |
|
|
img_path="./inference/images/7dd9ef45-f197db95.jpg"): |
|
|
|
|
|
ort.set_default_logger_severity(4) |
|
|
onnx_path = f"./weights/{weight}" |
|
|
ort_session = ort.InferenceSession(onnx_path) |
|
|
print(f"Load {onnx_path} done!") |
|
|
|
|
|
outputs_info = ort_session.get_outputs() |
|
|
inputs_info = ort_session.get_inputs() |
|
|
|
|
|
for ii in inputs_info: |
|
|
print("Input: ", ii) |
|
|
for oo in outputs_info: |
|
|
print("Output: ", oo) |
|
|
|
|
|
print("num outputs: ", len(outputs_info)) |
|
|
|
|
|
save_det_path = f"./pictures/detect_onnx.jpg" |
|
|
save_da_path = f"./pictures/da_onnx.jpg" |
|
|
save_ll_path = f"./pictures/ll_onnx.jpg" |
|
|
save_merge_path = f"./pictures/output_onnx.jpg" |
|
|
|
|
|
img_bgr = cv2.imread(img_path) |
|
|
height, width, _ = img_bgr.shape |
|
|
|
|
|
|
|
|
img_rgb = img_bgr[:, :, ::-1].copy() |
|
|
|
|
|
|
|
|
canvas, r, dw, dh, new_unpad_w, new_unpad_h = resize_unscale(img_rgb, (640, 640)) |
|
|
|
|
|
img = canvas.copy().astype(np.float32) |
|
|
img /= 255.0 |
|
|
img[:, :, 0] -= 0.485 |
|
|
img[:, :, 1] -= 0.456 |
|
|
img[:, :, 2] -= 0.406 |
|
|
img[:, :, 0] /= 0.229 |
|
|
img[:, :, 1] /= 0.224 |
|
|
img[:, :, 2] /= 0.225 |
|
|
|
|
|
img = img.transpose(2, 0, 1) |
|
|
|
|
|
img = np.expand_dims(img, 0) |
|
|
|
|
|
|
|
|
det_out, da_seg_out, ll_seg_out = ort_session.run( |
|
|
['det_out', 'drive_area_seg', 'lane_line_seg'], |
|
|
input_feed={"images": img} |
|
|
) |
|
|
|
|
|
det_out = torch.from_numpy(det_out).float() |
|
|
boxes = non_max_suppression(det_out)[0] |
|
|
boxes = boxes.cpu().numpy().astype(np.float32) |
|
|
|
|
|
if boxes.shape[0] == 0: |
|
|
print("no bounding boxes detected.") |
|
|
return |
|
|
|
|
|
|
|
|
boxes[:, 0] -= dw |
|
|
boxes[:, 1] -= dh |
|
|
boxes[:, 2] -= dw |
|
|
boxes[:, 3] -= dh |
|
|
boxes[:, :4] /= r |
|
|
|
|
|
print(f"detect {boxes.shape[0]} bounding boxes.") |
|
|
|
|
|
img_det = img_rgb[:, :, ::-1].copy() |
|
|
for i in range(boxes.shape[0]): |
|
|
x1, y1, x2, y2, conf, label = boxes[i] |
|
|
x1, y1, x2, y2, label = int(x1), int(y1), int(x2), int(y2), int(label) |
|
|
img_det = cv2.rectangle(img_det, (x1, y1), (x2, y2), (0, 255, 0), 2, 2) |
|
|
|
|
|
cv2.imwrite(save_det_path, img_det) |
|
|
|
|
|
|
|
|
da_seg_out = da_seg_out[:, :, dh:dh + new_unpad_h, dw:dw + new_unpad_w] |
|
|
ll_seg_out = ll_seg_out[:, :, dh:dh + new_unpad_h, dw:dw + new_unpad_w] |
|
|
|
|
|
da_seg_mask = np.argmax(da_seg_out, axis=1)[0] |
|
|
ll_seg_mask = np.argmax(ll_seg_out, axis=1)[0] |
|
|
print(da_seg_mask.shape) |
|
|
print(ll_seg_mask.shape) |
|
|
|
|
|
color_area = np.zeros((new_unpad_h, new_unpad_w, 3), dtype=np.uint8) |
|
|
color_area[da_seg_mask == 1] = [0, 255, 0] |
|
|
color_area[ll_seg_mask == 1] = [255, 0, 0] |
|
|
color_seg = color_area |
|
|
|
|
|
|
|
|
color_seg = color_seg[..., ::-1] |
|
|
color_mask = np.mean(color_seg, 2) |
|
|
img_merge = canvas[dh:dh + new_unpad_h, dw:dw + new_unpad_w, :] |
|
|
img_merge = img_merge[:, :, ::-1] |
|
|
|
|
|
|
|
|
img_merge[color_mask != 0] = \ |
|
|
img_merge[color_mask != 0] * 0.5 + color_seg[color_mask != 0] * 0.5 |
|
|
img_merge = img_merge.astype(np.uint8) |
|
|
img_merge = cv2.resize(img_merge, (width, height), |
|
|
interpolation=cv2.INTER_LINEAR) |
|
|
for i in range(boxes.shape[0]): |
|
|
x1, y1, x2, y2, conf, label = boxes[i] |
|
|
x1, y1, x2, y2, label = int(x1), int(y1), int(x2), int(y2), int(label) |
|
|
img_merge = cv2.rectangle(img_merge, (x1, y1), (x2, y2), (0, 255, 0), 2, 2) |
|
|
|
|
|
|
|
|
da_seg_mask = da_seg_mask * 255 |
|
|
da_seg_mask = da_seg_mask.astype(np.uint8) |
|
|
da_seg_mask = cv2.resize(da_seg_mask, (width, height), |
|
|
interpolation=cv2.INTER_LINEAR) |
|
|
|
|
|
|
|
|
ll_seg_mask = ll_seg_mask * 255 |
|
|
ll_seg_mask = ll_seg_mask.astype(np.uint8) |
|
|
ll_seg_mask = cv2.resize(ll_seg_mask, (width, height), |
|
|
interpolation=cv2.INTER_LINEAR) |
|
|
|
|
|
cv2.imwrite(save_merge_path, img_merge) |
|
|
cv2.imwrite(save_da_path, da_seg_mask) |
|
|
cv2.imwrite(save_ll_path, ll_seg_mask) |
|
|
|
|
|
print("detect done.") |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
parser = argparse.ArgumentParser() |
|
|
parser.add_argument('--weight', type=str, default="yolop-640-640.onnx") |
|
|
parser.add_argument('--img', type=str, default="./inference/images/9aa94005-ff1d4c9a.jpg") |
|
|
args = parser.parse_args() |
|
|
|
|
|
infer_yolop(weight=args.weight, img_path=args.img) |
|
|
""" |
|
|
PYTHONPATH=. python3 ./test_onnx.py --weight yolop-640-640.onnx --img test.jpg |
|
|
""" |
|
|
|