【芝士推理】YOLO_Line_Segment Analysis

道路分割

找到道路分割的onnx,分析其onnx的大致使用逻辑,然后写出最简洁版本predict.py

  1. 分析segment_onnx,查看输入输出

            a. 输入 [1, 3, 512, 896]

                 b. 输出 [1, 512, 896, 4], 并且是概率值,仅不确定4通道代表什么,下面猜测

                            马路边边

                            不可行使区域

                            车道线

                            可行使区域

      2. 查看代码,找到onnx的预处理,分析预处理逻辑

                c. Normalize -> mean = 0 , norm = 1/255.0 // 这里已经除过255了,所以在后面就不用除了

                d. 对输入图像直接resize到 [512, 896]

                e. 确定输入的就是BGR图像

                f. Normalize = (src_image - normalize.mean) * normalize.norm

      3. 针对获得的信息,编写predict.py, 尝试写出来

import onnxruntime
import cv2
import numpy as np

session = onnxruntime.InferenceSession("workspace/road-segmentation-adas.onnx", providers=["CPUExecutionProvider"])

image = cv2.imread("workspace/imgs/dashcam_00.jpg")
image = cv2.resize(image, (896, 512))  // 因为原图在norm的时候除了255,所以这里不用再除一次了
image_tensor = (image.astype(np.float32))  
image_tensor = image_tensor.transpose(2, 0, 1)[None]  // ONNX模型通常期望输入的格式是(通道, 高度, 宽度)

prob = session.run(
    ["tf.identity"], {"data": image_tensor}

)[0]

cv2.imwrite("prob0.jpg", prob[0, :, :, 2] * 255)

深度估计

从这里可以分析到的结果

  1. 输入[1, 3, 256, 512] 输出[1, 1, 256, 512]

  2. 它的输出只需要'2499',其他输出都多余

  3. NCHW is True :即直接resize

  4. IS_RGB is True :即需要BGR转RGB

从下图这里得到均值和方差

      5. normalize.mean = 0.485f norm = 0.229f

  • new_mean = mean * 255

  • new_norm = 1 / (norm * 255)

  • y = (x - new_mean) * new_norm --> y = (x / 255 - mean) / norm

分析差不多了,开始写代码

import onnxruntime
import cv2
import numpy as np
import matplotlib.pyplot as plt 
session = onnxruntime.InferenceSession("workspace/ldrn_kitti_resnext101_pretrained_data_grad_256x512.onnx", providers=["CPUExecutionProvider"])

image = cv2.imread("workspace/imgs/dashcam_00.jpg")
image = cv2.resize(image, (512, 256))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

image_tensor = (image / 255.0)
mean = [0.485, 0.456, 0.406]
norm = [0.229, 0.224, 0.225]
image_tensor = ((image_tensor - mean) / norm).astype(np.float32)
image_tensor = image_tensor.transpose(2, 0, 1)[None]

prob = session.run(
    ["2499"], {"input.1": image_tensor}

)[0]

# # cv
# prob = prob[0, 0] * -5 + 255
# y = int(prob.shape[0] * 0.18)
# prob = prob[y:]
# cv2.imwrite("depth.jpg", prob)

# plt
prob = prob[0, 0]
y = int(prob.shape[0] * 0.18)
prob = prob[y:]
plt.imsave("depth.jpg", prob, cmap='plasma_r')
# cmap='plasma_r'  反向等离子映射

消融实验

不加初始化

cv深度估计图

plt深度估计图

车道线检测

根据实际任务获取的先验知识

半张图,四条线,18点,200份+1份(是否存在),位置概率

输入 :[1, 3, 288, 800]

输出 :[1, 201, 18, 4]

先验 :

  • 只需要识别4根线

  • 车道线都是地面上,所以y方向可以中图像中心开始,也就是anchor起始坐标是图像中心到图像底部

  • 线是连续的,但可以用离散的点表示,所以选择18个点表示一条线

  • 因此回归一个点,其y坐标已知,x坐标需要回归出来

  • 对于x回归,采用了位置概率来表示,划分为200个网格表示坐标

  • 对于车道线的点是否存在的问题,采用第201个概率表示;若不存在,则该点最大

图像的预处理 : image / 255

图像需要BGR --> RGB

图像直接resize [288, 800]

后处理部分

  • 对0—200维度进行softmax

  • 对位置概率和位置索引点乘相加得到location,此时location是[18, 4]

  • 对原始输出的最大值进行判断,决定该点是否存在;

  • 最后过滤得到4根线的坐标

import onnxruntime
import cv2
import numpy as np
import matplotlib.pyplot as plt 
import scipy.special
session = onnxruntime.InferenceSession("workspace/ultra_fast_lane_detection_culane_288x800.onnx", providers=["CPUExecutionProvider"])

image = cv2.imread("workspace/imgs/dashcam_00.jpg")
show = image.copy()

image = cv2.resize(image, (800, 288))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_tensor = (image / 255.0).astype(np.float32)
image_tensor = image_tensor.transpose(2, 0, 1)[None]

pred = session.run(
    ["200"], {"input.1": image_tensor}
)[0][0]

prob = scipy.special.softmax(pred[:-1, :, :], axis=0)
idx = np.arange(200) + 1
idx = idx.reshape(-1, 1, 1)
loc = np.sum(prob * idx, axis=0)

col_sample = np.linspace(0, 800 - 1, 200)
col_sample_w = col_sample[1] - col_sample[0]
print(col_sample_w)

pred = np.argmax(pred, axis=0)
loc[pred == 200] = 0

ys = np.array([121, 131, 141, 150, 160, 170, 180, 189, 199, 209, 219, 228, 238, 248, 258, 267, 277, 287])

xs = loc * col_sample_w * show.shape[1] / 800
ys = ys * show.shape[0] / 288

colors = [(0, 0, 255), (0, 255, 0), (0, 255, 0), (0, 0, 255)]

for iline in range(4):
    for x, y in zip(xs[:, iline], ys):
        if x == 0:
            continue

        cv2.circle(show, (int(x), int(y)), 5, colors[iline], -1, 16)
cv2.imwrite("lane.jpg", show)

print(pred.shape)

推理结果

参考仓库

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值