重新分析一下def pose_tracking(pose_results, max_tracks=2, thre=30):

tracking_inputs = [
    [[0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11],
     [0.21, 0.32, 0.43, 0.54, 0.65, 0.76, 0.87, 0.98, 1.09, 1.20]],  # 第 1 帧
    [[0.15, 0.26, 0.37, 0.48, 0.59, 0.70, 0.81, 0.92, 1.03, 1.14],
     [0.24, 0.35, 0.46, 0.57, 0.68, 0.79, 0.90, 1.01, 1.12, 1.23]],  # 第 2 帧
    [[0.18, 0.29, 0.40, 0.51, 0.62, 0.73, 0.84, 0.95, 1.06, 1.17],
     [0.27, 0.38, 0.49, 0.60, 0.71, 0.82, 0.93, 1.04, 1.15, 1.26]]   # 第 3 帧
]

 其中pose_results这个形参被tracking_inputs这个实参赋值了

这个时候分析一下代码思路

def pose_tracking(pose_results, max_tracks=2, thre=30):
    tracks, num_tracks = [], 0
    num_joints = None
    for idx, poses in enumerate(pose_results):
        if len(poses) == 0:
            continue
        if num_joints is None:
            num_joints = poses[0].shape[0]
        track_proposals = [t for t in tracks if t['data'][-1][0] > idx - thre]
        n, m = len(track_proposals), len(poses)
        scores = np.zeros((n, m))

        for i in range(n):
            for j in range(m):
                scores[i][j] = dist_ske(track_proposals[i]['data'][-1][1], poses[j])

        row, col = linear_sum_assignment(scores)
        for r, c in zip(row, col):
            track_proposals[r]['data'].append((idx, poses[c]))
        if m > n:
            for j in range(m):
                if j not in col:
                    num_tracks += 1
                    new_track = dict(data=[])
                    new_track['track_id'] = num_tracks
                    new_track['data'] = [(idx, poses[j])]
                    tracks.append(new_track)
    if num_joints is None:
        return None, None
    tracks.sort(key=lambda x: -len(x['data']))
    result = np.zeros((max_tracks, len(pose_results), num_joints, 3), dtype=np.float16)
    for i, track in enumerate(tracks[:max_tracks]):
        for item in track['data']:
            idx, pose = item
            result[i, idx] = pose
    return result[..., :2], result[..., 2]

for idx, poses in enumerate(pose_results):

代入tracking_inputs这个实参

for idx, poses in enumerate(tracking_inputs):
    print(f"Frame {idx}: {poses}")

这段代码的作用是:

  1. 遍历 tracking_inputs 列表中的每个元素。
  2. 对于每个元素,获取它的索引 idx 和相应的 poses 数据。
  3. 打印出当前帧的索引和该帧包含的 poses 数据。

 

具体输出如下:

Frame 0: [[0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11], [0.21, 0.32, 0.43, 0.54, 0.65, 0.76, 0.87, 0.98, 1.09, 1.20]]
Frame 1: [[0.15, 0.26, 0.37, 0.48, 0.59, 0.70, 0.81, 0.92, 1.03, 1.14], [0.24, 0.35, 0.46, 0.57, 0.68, 0.79, 0.90, 1.01, 1.12, 1.23]]
Frame 2: [[0.18, 0.29, 0.40, 0.51, 0.62, 0.73, 0.84, 0.95, 1.06, 1.17], [0.27, 0.38, 0.49, 0.60, 0.71, 0.82, 0.93, 1.04, 1.15, 1.26]]

这段代码的主要作用是遍历并输出 tracking_inputs 中每个帧的 poses 数据。

继续执行 if len(poses) == 0:

发现len(poses)是2,不满足,于是不执行continue

 继续执行if num_joints is None:

发现满足,于是执行num_joints = poses[0].shape[0]

由于poses[0]=[0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11],于是poses[0].shape[0]等于多少?

  1. shape 是一个属性,用于获取列表或数组的维度信息。对于一维列表或数组,shape 返回一个只有一个元素的元组。

  2. 对于一维列表或数组,shape[0] 就等同于获取列表或数组的长度。这是因为对于一维数据结构,只有一个维度,所以取第 0 个维度就是获取整个数据结构的长度。

  

继续执行 track_proposals = [t for t in tracks if t['data'][-1][0] > idx - thre]

由于tracks初始化为空列表,所以track_proposals也是空列表

 继续执行n, m = len(track_proposals), len(poses)

于是n=0,m=2

 继续执行scores = np.zeros((0, 2))

于是scores是空数组

继续执行下面

for i in range(0):
            for j in range(2):
                scores[i][j] = dist_ske(track_proposals[i]['data'][-1][1], poses[j])

发现什么也不做,因为最外层循环条件不满足

继续执行row, col = linear_sum_assignment(scores)

由于scores是空数组

当 scores 是一个空数组时:

  1. row 列表会是一个空列表 []
  2. col 列表也会是一个空列表 []

这是因为当 scores 为空时,意味着没有任何可以分配的元素,因此 linear_sum_assignment() 函数无法找到任何匹配,返回的行和列索引都是空列表。

继续执行

  for r, c in zip(row, col):
            track_proposals[r]['data'].append((idx, poses[c]))

发现什么也不做,因为最外层循环条件不满足

继续执行下面代码

  if 2 > 0:
            for j in range(2):
                if j not in col:
                    num_tracks += 1
                    new_track = dict(data=[])
                    new_track['track_id'] = num_tracks
                    new_track['data'] = [(idx, poses[j])]
                    tracks.append(new_track)

  1. 首先,if 2 > 0: 这个条件成立,因此会进入 for 循环。
  2. for j in range(2): 会执行两次循环,因为 range(2) 产生的序列是 [0, 1]
  3. 在每次循环中,if j not in col: 这个条件都会成立,因为 col 是一个空列表 []
  4. 因此,每次循环中都会执行以下操作:
    • num_tracks += 1num_tracks 的值会增加 1。
    • new_track = dict(data=[])创建一个新的字典 new_track
    • new_track['track_id'] = num_tracks:给新的字典设置 'track_id' 键,值为当前的 num_tracks
    • new_track['data'] = [(idx, poses[j])]:给新的字典设置 'data' 键,值为一个包含当前 idx 和 poses[j] 的元组列表。
    • tracks.append(new_track)将新创建的字典 new_track 添加到 tracks 列表中。

所以,如果 col 是一个空列表,那么这段代码会根据 poses 列表的长度(这里是 2)创建相应数量的新的字典(track)并添加到 tracks 列表中。每个新创建的字典都有一个唯一的 'track_id' 和一个包含当前帧信息的 'data' 列表。

于是最终的 tracks 列表应该是:

tracks = [
    {
        'track_id': 1,
        'data': [(0, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11])]
    },
    {
        'track_id': 2,
        'data': [(0, [0.21, 0.32, 0.43, 0.54, 0.65, 0.76, 0.87, 0.98, 1.09, 1.20])]
    }
]

接着继续执行第2轮外循环

  for idx, poses in enumerate(pose_results):

这个时候idx是变成了1,而poses是 [[0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11], [0.13, 0.24, 0.35, 0.46, 0.57, 0.68, 0.79, 0.9, 1.01, 1.12]]

if len(poses) == 0:发现不满足,不执行continue 

继续if num_joints is None:发现不满足,于是不执行num_joints = poses[0].shape[0]

继续执行track_proposals = [t for t in tracks if t['data'][-1][0] > idx - thre]

由于tracks列表在第1轮循环的时候是如下这样

tracks = [
    {
        'track_id': 1,
        'data': [(0, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11])]
    },
    {
        'track_id': 2,
        'data': [(0, [0.21, 0.32, 0.43, 0.54, 0.65, 0.76, 0.87, 0.98, 1.09, 1.20])]
    }
]

if t['data'][-1][0] > idx - thre条件发现满足

所以没有起到过滤作用

  1. t 代表的是 tracks 列表中的每一个字典对象。
  2. t['data'] 是获取该字典中 'data' 键对应的值,也就是一个列表。
  3. t['data'][-1] 是获取该列表中的最后一个元素,也就是一个元组。
  4. t['data'][-1][0] 是获取该元组的第一个元素,也就是一个整数值。

所以,这行代码的作用是:

  • 对于 tracks 列表中的每个字典 t,
  • 获取 t 中 'data' 键对应的列表,
  • 获取该列表的最后一个元组,
  • 并获取该元组的第一个元素。

这个值通常会用作一些条件判断,比如在你的代码中,用于判断 idx - thre 的大小。

总之, t['data'][-1][0] 就是获取每个轨迹数据列表中最后一个元素的第一个值,即帧数。这是一个常见的用法。

如果 t['data'][-1][0] > idx - thre 这个条件永远成立,那么 track_proposals 列表就会包含 tracks 列表中的所有字典对象。

track_proposals 的结构和 tracks 列表完全一样,包含两个字典对象:

track_proposals = [
    {
        'track_id': 1,
        'data': [(0, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11])]
    },
    {
        'track_id': 2,
        'data': [(0, [0.21, 0.32, 0.43, 0.54, 0.65, 0.76, 0.87, 0.98, 1.09, 1.20])]
    }
]

每个字典对象都有两个键:

  1. 'track_id': 表示轨迹 ID
  2. 'data': 表示该轨迹的数据,是一个列表,列表中的每个元素都是一个二元组,第一个元素是帧数,第二个元素是一个列表,表示该帧中的数据。

所以, track_proposals 的结构和 tracks 完全相同,只是它包含了 tracks 列表中的所有元素。

  n, m = len(track_proposals), len(poses)

所以n=2,m=2

  scores = np.zeros((n, m))

先全0二维数组,后面再重新赋值覆盖即可

 for i in range(2):
            for j in range(2):
                scores[i][j] = dist_ske(track_proposals[i]['data'][-1][1], poses[j])

track_proposals[0]['data'][-1][1],其中track_proposals = [
{
'track_id': 1,
'data': [(0, [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11])]
},
{
'track_id': 2,
'data': [(0, [0.21, 0.32, 0.43, 0.54, 0.65, 0.76, 0.87, 0.98, 1.09, 1.20])]
}
],那么track_proposals[0]['data'][-1][1]什么语法

解释一下 track_proposals[0]['data'][-1][1] 这个语法:

  1. track_proposals[0] 表示获取 track_proposals 列表中的第一个字典对象。

  2. track_proposals[0]['data'] 表示获取该字典对象中 'data' 键对应的值,也就是一个列表。

  3. track_proposals[0]['data'][-1] 表示获取该列表中的最后一个元素,也就是一个二元组。

  4. track_proposals[0]['data'][-1][1] 表示获取这个二元组的第二个元素,也就是一个列表。

所以,这行代码的作用是:

  • 从 track_proposals 列表中获取第一个字典对象,
  • 从该字典对象的 'data' 键中获取列表,
  • 从该列表中获取最后一个元素(也就是一个二元组),
  • 从这个二元组中获取第二个元素(也就是一个列表)。

也就是说, track_proposals[0]['data'][-1][1] 的结果是 [0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11]

而poses[0]是[0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11]

当i=0,j=0的时候,于是发现ske1, ske2两个参数相同

开始执行

def dist_ske(ske1, ske2):
    dist = np.linalg.norm(ske1[:, :2] - ske2[:, :2], axis=1) * 2
    diff = np.abs(ske1[:, 2] - ske2[:, 2])
    return np.sum(np.maximum(dist, diff))

至于ske1=[0.12, 0.23, 0.34, 0.45, 0.56, 0.67, 0.78, 0.89, 1.0, 1.11],那么ske1[:, :2]是什么语法?
可以pycharm上简单print测试一下

pyskl/demo/demo_skeleton.py at main · kennymckormick/pyskl · GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值