前记
最近几天对CVPR2018的一篇行人轨迹预测Social GAN进行了复现,过程中发现ETH数据集中行人的坐标已经转为了世界坐标,因此无法进行可视化,询问博主后得知要通过单应矩阵H将世界坐标反转为像素坐标,经过多次尝试成功反转,以此记录。
ETH数据集
官方链接下载的数据集分为两个文件夹seq_eth,seq_hotel以及README.txt,每个文件夹中为视频以及对应的标注信息,主要关注两个文件:obsmat.txt(标注)以及H.txt(单应性矩阵)。注:SGAN作者还对obsmat.txt进行了预处理,仅保留了[frame_id, p_id, wpx, wpy],若复现SGAN建议直接下载作者提供的链接(否则要改动代码)
转换公式
这个不难理解,左乘逆矩阵反转嘛,但是转换前和转换后还需要对两个坐标做一点处理。
1.worldpos为3x1列向量,[wpx, wpy, wpz],前两个元素直接读取就好,但ETH数据集没有使用wpz,标注中wpz全为0,转换前需要将wpz设置为1,即
2.求得的pixelpos同理,[px, py, pz],但需要将pz再转为1,即 ,像素坐标系中pz是无意义的,这可能也是为什么要再除以pz。
详细代码
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_)
其中read_file为SGAN作者提供的方法,稍做了一点修改(标注文件不一致的问题)文章来源:https://www.toymoban.com/news/detail-769588.html
完整可视化代码
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
结语
本身方向并不是轨迹预测,机缘巧合下找到SGAN并进行复现,并且发现该方向相关资料较少,可能这个反转操作对大佬来说确是小菜一碟,在此献丑还望大家海涵,欢迎学术交流。文章来源地址https://www.toymoban.com/news/detail-769588.html
到了这里,关于行人轨迹预测ETH数据集坐标转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!