Predicción de trayectoria peatonal Conversión de coordenadas del conjunto de datos ETH

Prefacio

En los últimos días, reproduje Social GAN, un artículo de predicción de trayectoria de peatones de CVPR 2018. Durante el proceso, descubrí que las coordenadas de los peatones en el conjunto de datos ETH se han convertido a coordenadas mundiales, por lo que no se pueden visualizar. Blogger, aprendí que se requiere la matriz de homografía H. Invierta las coordenadas mundiales en coordenadas de píxeles y registre la inversión exitosa después de múltiples intentos.

conjunto de datos ETH

El conjunto de datos descargado desde el enlace oficial se divide en dos carpetas: seq_eth, seq_hotel y README.txt. Cada carpeta contiene videos y la información de anotación correspondiente. Nos centramos principalmente en dos archivos: obsmat.txt (anotación) y H.txt (homografía). matriz). Nota: El autor de SGAN también preprocesó obsmat.txt y solo retuvo [frame_id, p_id, wpx, wpy]. Si se reproduce SGAN, se recomienda descargar directamente el enlace proporcionado por el autor (de lo contrario, se debe cambiar el código)

Fórmula de conversión

pospíxel = H^{-1} * posmundial
Esto no es difícil de entender: la matriz inversa multiplicada por la izquierda está invertida, pero es necesario realizar algún procesamiento de las dos coordenadas antes y después de la conversión.

1.worldpos es un vector de columna de 3x1, [wpx, wpy, wpz]. Los dos primeros elementos se pueden leer directamente. Sin embargo, el conjunto de datos ETH no usa wpz. El wpz en la anotación es todo 0. Debe configurar wpz a 1 antes de la conversión. Ahora mismo   posmundial = \begin{bmatrix}wpx \\ wpy \\ 1 \end{bmatrix}

2. Los pixelpos obtenidos son los mismos que [px, py, pz], pero pz debe convertirse a 1, es decir,  pixelpos = \begin{bmatrix}px/pz \\ py/pz \\ 1 \end{bmatrix}pz no tiene sentido en el sistema de coordenadas de píxeles, por lo que puede ser necesario dividir por pz nuevamente. .

Código detallado

    data = read_file('./datasets_/eth/test/obsmat.txt')
    H = np.array([
        [2.8128700e-02, 2.0091900e-03, -4.6693600e+00],
        [8.0625700e-04, 2.5195500e-02, -5.0608800e+00],
        [3.4555400e-04, 9.2512200e-05, 4.6255300e-01]
    ])
    H_inv = np.linalg.inv(H)
    frames = np.unique(data[:, 0]).tolist()  # 总帧数
    frame_data = []
    pixel_poses = []
    for frame in frames:
        frame_data.append(data[frame == data[:, 0], :])  # 重组gt, frame_data列表的每一个元素代表当前帧下所有Person的出现情况
    for frame_data_ in frame_data:
        world_pos = np.vstack((frame_data_[:, 2], frame_data_[:, 4]))
        world_pos = np.vstack((world_pos, np.ones((world_pos.shape[1]))))
        pixel_pos = np.dot(H_inv, world_pos)
        pixel_pos_ = pixel_pos[:2, :] / pixel_pos[2:, :]
        pixel_poses.append(pixel_pos_)

Entre ellos, read_file es un método proporcionado por el autor de SGAN, con una ligera modificación (el problema de la inconsistencia en los archivos marcados)

código visual completo

import numpy as np
import cv2


def read_file(_path, delim='\t'):
    data = []
    if delim == 'tab':
        delim = '\t'
    elif delim == 'space':
        delim = ' '
    delim = ' '
    with open(_path, 'r') as f:
        for line in f:
            line = line.strip().split(delim)
            line = [i for i in line if not i == '']
            line = [float(i) for i in line]
            data.append(line)
    return np.asarray(data)


if __name__ == '__main__':
    data = read_file('./datasets_/eth/test/obsmat.txt')
    H = np.array([
        [2.8128700e-02, 2.0091900e-03, -4.6693600e+00],
        [8.0625700e-04, 2.5195500e-02, -5.0608800e+00],
        [3.4555400e-04, 9.2512200e-05, 4.6255300e-01]
    ])
    H_inv = np.linalg.inv(H)
    frames = np.unique(data[:, 0]).tolist()  # 总帧数
    frame_data = []
    pixel_poses = []
    for frame in frames:
        frame_data.append(data[frame == data[:, 0], :])  # 重组gt, frame_data列表的每一个元素代表当前帧下所有Person的出现情况
    for frame_data_ in frame_data:
        world_pos = np.vstack((frame_data_[:, 2], frame_data_[:, 4]))
        world_pos = np.vstack((world_pos, np.ones((world_pos.shape[1]))))
        pixel_pos = np.dot(H_inv, world_pos)
        pixel_pos_ = pixel_pos[:2, :] / pixel_pos[2:, :]
        pixel_poses.append(pixel_pos_)

    video = cv2.VideoCapture(r'D:\yjy\PycharmProjects\sgan-master\ewap_dataset\seq_eth\seq_eth.avi')
    k = 0
    index = 0
    while True:
        _, frame = video.read()
        if frame is None:
            break
        img = frame.copy()
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        if k == frames[index]:
            positions = pixel_poses[index]
            positions = np.transpose(positions)
            for p in positions:
                cy, cx = np.int32(p)
                cv2.rectangle(img, (cx - 10, cy - 20), (cx + 10, cy + 20), (255, 255, 255), thickness=2)
            index = index + 1
            cv2.imwrite('./imgs/{}.jpg'.format(k), img)
        cv2.imshow('video', img)
        cv2.waitKey(10)
        k = k + 1

Conclusión

La dirección en sí no es una predicción de trayectoria. Encontré SGAN por casualidad y lo reproduje, y descubrí que hay menos información relacionada con esta dirección. Tal vez esta operación de reversión sea pan comido para los grandes. Espero que todos tengan paciencia. A mí por mostrar mi vergüenza aquí. Los intercambios académicos son bienvenidos.

Supongo que te gusta

Origin blog.csdn.net/yjy123nn/article/details/129637563
Recomendado
Clasificación