Правильный способ извлечения 3D-точек из изображения глубины

#python #opencv #depth

#python #opencv #глубина

Вопрос:

Я использую следующий код для извлечения 3D-точек из изображения глубины,

 def retrieve_3d_points(K , depth_image_path):
    depth_factor = 1000.0

    depth_img = cv2.imread(depth_image_path, cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH) / depth_factor

    row, col = depth_img.shape

    pts3d = []
    fx = K[0][0]
    cx = K[0][2]

    fy = K[1][1]
    cy = K[1][2]

    for i in range(row):
        for j in range(col):
            depth = depth_img[i][j]
            x, y = i, j
            if depth > 0.0:
                x3D = (x - cx) * depth / fx
                y3D = (y - cy) * depth / fy
                z3D = depth
                pts3d.append([x3D, y3D, z3D])
            else:
                pts3d.append([-1, -1, -1])
    return pts3d
 

К сожалению, точки извлечения не так точны с точки зрения масштаба. Правильно ли я извлекаю?

Ответ №1:

Возможно, он генерируется с расстояния до камеры, а не нормируется до определенного диапазона. Вам придется перебирать его, чтобы найти экстенты: минимальное значение, максимальное значение.

 minimum, maximum = 0, 0
for i in range(row):
    for j in range(col):
        pixel = depth_img[i][j]
        if pixel < minimum:  minimum = pixel
        elif pixel > maximum:  maximum = pixel

extent = maximum -minimum
normalized = [ [], [] ]  ##  normalize values within range 0-1

for i in range(row):
    for j in range(col):
        ##  subtract minimum from every point, then divide by extent
        normalized[i][j] = ( depth_img[i][j] -minimum ) /extent

---

scale = 255  ##  optional, if you expect a different range of values.  0-255
for i in range(row):
    for j in range(col):
        normalized[i][j] = ( depth_img[i][j] -minimum ) /extent *scale
 

Затем запустите свой retrieve_3d_points() массив on с ожидаемыми значениями.

Комментарии:

1. Возможно, в cv2, numpy и др. встроена такая функция нормализации диапазона. Я не запомнил все эти модули, поэтому вам придется искать их, или, возможно, кто-то еще знает. Я подозреваю, что причиной является диапазон.