透视变换相关概念
透视变换(Perspective Transformation)就是将图片根据变换矩阵M投影到一个新的视觉平面,也叫做投影映射。意思就是说,把一个平面投影到一个垂直的画面,也就是俯视图。其变换公式为:
难得写了,直接插入论文截图了。将就看一下。
所以,只要知道了要做透视变换的对应的4个坐标点的像素点坐标和真实值坐标,就可以求出透视变换矩阵M,在本系统中,根据坐标变换求出的透视变换矩阵为:
在得到目标的透视变换矩阵之后,可以将跟踪目标的坐标进行变换,从像素坐标转换为真实坐标,而通过不同帧之间的真实坐标位置,可以求出目标相对位移,本文中采用的办法是计算相邻20帧之间的目标框中心坐标欧氏距离x。而距离除以时间(帧率)t,就是目标移动速度v。
一、关键代码部分
用到我们求出来的M矩阵。
def get_real_postion(box_xyxy):
M = np.array([[2.57437805e-02, 2.12758516e-03, -1.58149788e+01],
[-1.33331750e-03, -3.95995299e-02, 3.01201758e+01],
[-1.14894491e-04, 2.55317950e-04, 1.00000000e+00]])
# print(M[0][0])
# box_xyxy = np.array([[317, 78, 340, 114], [361, 177, 419, 220]])
x = np.ones(box_xyxy.shape[0])
new_box = np.insert(box_xyxy, 2, values=x, axis=1)
new_box = np.insert(new_box, 5, values=x, axis=1)
# print(new_box)
temp_list = []
for item in new_box:
i = item.reshape(2, 3)
temp_list.append(i.transpose())
# print(i.transpose())
temp_a = []
for _item in temp_list:
# print(_item)
zsjfenzi = M[0][0] * _item[..., 0][0] + M[0][1] * _item[..., 0][1] + M[0][2]
fenmu = M[2][0] * _item[..., 0][0] + M[2][1] * _item[..., 0][1] + M[2][2]
z_new_x = zsjfenzi / fenmu
_zsjfenzi = M[1][0] * _item[..., 0][0] + M[1][1] * _item[..., 0][1] + M[1][2]
z_new_y = _zsjfenzi / fenmu
yxjfenzi = M[0][0] * _item[..., 1][0] + M[0][1] * _item[..., 1][1] + M[0][2]
_fenmu = M[2][0] * _item[..., 1][0] + M[2][1] * _item[..., 1][1] + M[2][2]
you_new_x = yxjfenzi / _fenmu
_yxjfenzi = M[1][0] * _item[..., 1][0] + M[1][1] * _item[..., 1][1] + M[1][2]
you_new_y = _yxjfenzi / _fenmu
temp_a.append([z_new_x, z_new_y, you_new_x, you_new_y])
return np.asarray(temp_a)
这儿就是拿到真实坐标了嘛,对吧,然后就进行进一步计算了。
def get_distance(x1, x2):
index = []
distance = []
id = []
for i in x1[1]:
# print(x1[1].index(i))
for j in x2[1]:
if i == j:
id.append(i)
index.append((list(x1[1]).index(i), list(x2[1]).index(j)))
# print(index)
for i, j in index:
# print(i, j)
temp1 = x1[0][i]
temp2 = x2[0][j]
temp1 = np.array(temp1).astype(np.float32)
temp2 = np.array(temp2).astype(np.float32)
# print(temp1, temp2)
'''
[-4.366818 24.003805 -3.4757879 23.0965 ] [-4.345595 24.066225 -3.4117692 23.064928 ]
[-1.7292873 20.202377 0.91213334 19.318773 ] [-1.3384868 35.61339 -0.25401056 36.335445 ]
'''
z_center_x = (temp1[0] + temp1[2]) / 2
z_center_y = (temp1[1] + temp1[3]) / 2
y_center_x = (temp2[0] + temp2[2]) / 2
y_center_y = (temp2[1] + temp2[3]) / 2
len = math.hypot(z_center_x - y_center_x, z_center_y - y_center_y) # (x1, y1)与(x2, y2)间的欧氏距离
# len_1 = math.sqrt((z_center_x - y_center_x) ** 2 + (z_center_y - y_center_y) ** 2) !一样的意思
# print(len)
# print(z_center_x, z_center_y, y_center_x, y_center_y)
distance.append(len)
distance = np.asarray(distance)
# print(distance)
# print(np.asarray(id))
return distance, np.asarray(id)
拿到距离,就可以用我之前的博客写的yolov4-deepsort程序调用啦,然后速度就求出来了。
二、有个问题
其实我觉得这个deepsort算法我还没有理解透,由于以上的内容都是我按照我自己的想法完成的,我也不知道这样子做对不对,后期我重新理解一下代码运行,重新完善一下吧。我总感觉某些地方还存在改进,,,,,加油加油!!!