3D點(diǎn)云目標(biāo)跟蹤的評(píng)價(jià)指標(biāo)及詳細(xì)代碼
作者:大森林 | 來(lái)源:計(jì)算機(jī)視覺(jué)工坊
添加微信:dddvisiona,備注:3D點(diǎn)云,拉你入群。文末附行業(yè)細(xì)分群。
3D點(diǎn)云目標(biāo)跟蹤的評(píng)價(jià)指標(biāo),可以根據(jù)跟蹤的目標(biāo)是單個(gè)還是多個(gè),分為單目標(biāo)跟蹤(SOT)和多目標(biāo)跟蹤(MOT)兩種。一般來(lái)說(shuō),SOT的評(píng)價(jià)指標(biāo)主要關(guān)注跟蹤的準(zhǔn)確性和魯棒性,而MOT的評(píng)價(jià)指標(biāo)則需要考慮跟蹤的完整性和一致性。
SOT的常用評(píng)價(jià)指標(biāo)有:
平均重疊率(Average Overlap Rate, AOR):表示預(yù)測(cè)的3D邊界框與真實(shí)的3D邊界框之間的重疊比例的平均值。
平均中心誤差(Average Center Error, ACE):表示預(yù)測(cè)的3D邊界框與真實(shí)的3D邊界框之間的中心點(diǎn)距離的平均值。
成功率(Success Rate, SR):表示預(yù)測(cè)的3D邊界框與真實(shí)的3D邊界框之間的重疊比例超過(guò)某個(gè)閾值(如0.5)的幀數(shù)占總幀數(shù)的比例。
精確率(Precision Rate, PR):表示預(yù)測(cè)的3D邊界框與真實(shí)的3D邊界框之間的中心點(diǎn)距離小于某個(gè)閾值(如1米)的幀數(shù)占總幀數(shù)的比例。
MOT的常用評(píng)價(jià)指標(biāo)有:
多目標(biāo)跟蹤精度(Multiple Object Tracking Accuracy, MOTA):綜合考慮了漏檢率、誤檢率和ID切換率對(duì)跟蹤精度的影響。
多目標(biāo)跟蹤精確度(Multiple Object Tracking Precision, MOTP):表示預(yù)測(cè)的3D邊界框與真實(shí)的3D邊界框之間的重疊比例或中心點(diǎn)距離的平均值。
跟蹤長(zhǎng)度(Track Length, TL):表示每個(gè)目標(biāo)被成功跟蹤的幀數(shù)。
跟蹤片段(Track Fragment, TF):表示每個(gè)目標(biāo)被中斷跟蹤的次數(shù)。
ID切換率(ID Switch Rate, ISR):表示每個(gè)目標(biāo)被錯(cuò)誤地分配給另一個(gè)ID或從另一個(gè)ID切換過(guò)來(lái)的次數(shù)。
評(píng)價(jià)指標(biāo)詳細(xì)代碼:
首先,我們需要導(dǎo)入一些必要的庫(kù),如numpy, scipy和sklearn。然后,我們需要定義一些輔助函數(shù),如計(jì)算兩個(gè)3D邊界框之間的重疊比例(IoU),計(jì)算兩個(gè)3D點(diǎn)之間的歐氏距離,以及使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián)。
這里也推薦「3D視覺(jué)工坊」新課程《面向自動(dòng)駕駛領(lǐng)域的3D點(diǎn)云目標(biāo)檢測(cè)全棧學(xué)習(xí)路線!(單模態(tài)+多模態(tài)/數(shù)據(jù)+代碼)》
import?numpy?as?npfrom?scipy.spatial.transform?import?Rotation?as?Rfrom?scipy.optimize?import?linear_sum_assignmentfrom?sklearn.metrics?import?pairwise_distances#?計(jì)算兩個(gè)3D邊界框之間的重疊比例(IoU)def?iou_3d(box1,?box2):????#?box1和box2都是7維向量,表示(x,?y,?z,?w,?l,?h,?yaw)????#?其中(x,?y,?z)是中心點(diǎn)坐標(biāo),(w,?l,?h)是寬度、長(zhǎng)度和高度,yaw是偏航角????#?返回兩個(gè)邊界框之間的IoU值,范圍在[0,?1]????#?將邊界框轉(zhuǎn)換為8個(gè)頂點(diǎn)的矩陣????box1_corners?=?box_to_corners(box1)????box2_corners?=?box_to_corners(box2)????#?計(jì)算兩個(gè)邊界框在每個(gè)軸上的投影區(qū)間????box1_xmin?=?np.min(box1_corners[:,?0])????box1_xmax?=?np.max(box1_corners[:,?0])????box1_ymin?=?np.min(box1_corners[:,?1])????box1_ymax?=?np.max(box1_corners[:,?1])????box1_zmin?=?np.min(box1_corners[:,?2])????box1_zmax?=?np.max(box1_corners[:,?2])????box2_xmin?=?np.min(box2_corners[:,?0])????box2_xmax?=?np.max(box2_corners[:,?0])????box2_ymin?=?np.min(box2_corners[:,?1])????box2_ymax?=?np.max(box2_corners[:,?1])????box2_zmin?=?np.min(box2_corners[:,?2])????box2_zmax?=?np.max(box2_corners[:,?2])????#?計(jì)算兩個(gè)邊界框在每個(gè)軸上的交集區(qū)間????inter_xmin?=?max(box1_xmin,?box2_xmin)????inter_xmax?=?min(box1_xmax,?box2_xmax)????inter_ymin?=?max(box1_ymin,?box2_ymin)????inter_ymax?=?min(box1_ymax,?box2_ymax)????inter_zmin?=?max(box1_zmin,?box2_zmin)????inter_zmax?=?min(box1_zmax,?box2_zmax)????#?如果沒(méi)有交集,返回0????if?inter_xmax?<?inter_xmin?or?inter_ymax?<?inter_ymin?or?inter_zmax?<?inter_zmin:????????return?0.0????#?計(jì)算交集區(qū)域的體積????inter_vol?=?(inter_xmax?-?inter_xmin)?*?(inter_ymax?-?inter_ymin)?*?(inter_zmax?-?inter_zmin)????#?計(jì)算兩個(gè)邊界框的體積????box1_vol?=?(box1_xmax?-?box1_xmin)?*?(box1_ymax?-?box1_ymin)?*?(box1_zmax?-?box1_zmin)????box2_vol?=?(box2_xmax?-?box2_xmin)?*?(box2_ymax?-?box2_ymin)?*?(box2_zmax?-?box2_zmin)????#?計(jì)算并返回IoU值????iou?=?inter_vol?/?(box1_vol?+?box2_vol?-?inter_vol)????return?iou#?將7維向量表示的邊界框轉(zhuǎn)換為8個(gè)頂點(diǎn)的矩陣表示def?box_to_corners(box):????#?輸入是一個(gè)7維向量,表示(x,?y,?z,?w,?l,?h,?yaw)????#?輸出是一個(gè)8x3的矩陣,表示8個(gè)頂點(diǎn)的坐標(biāo)????#?提取邊界框的參數(shù)????x,?y,?z,?w,?l,?h,?yaw?=?box????#?計(jì)算旋轉(zhuǎn)矩陣????rot?=?R.from_euler('z',?yaw).as_matrix()????#?計(jì)算邊界框的中心點(diǎn)????center?=?np.array([x,?y,?z])????#?計(jì)算邊界框的8個(gè)頂點(diǎn)的相對(duì)坐標(biāo)????x_corners?=?np.array([w,?w,?-w,?-w,?w,?w,?-w,?-w])?/?2????y_corners?=?np.array([l,?-l,?-l,?l,?l,?-l,?-l,?l])?/?2????z_corners?=?np.array([h,?h,?h,?h,?-h,?-h,?-h,?-h])?/?2????corners?=?np.vstack((x_corners,?y_corners,?z_corners))????#?通過(guò)旋轉(zhuǎn)和平移,將相對(duì)坐標(biāo)轉(zhuǎn)換為絕對(duì)坐標(biāo)????corners?=?np.dot(rot,?corners).T?+?center????return?corners#?計(jì)算兩個(gè)3D點(diǎn)之間的歐氏距離def?euclidean_distance(point1,?point2):????#?point1和point2都是3維向量,表示(x,?y,?z)????#?返回兩個(gè)點(diǎn)之間的歐氏距離????#?計(jì)算兩個(gè)點(diǎn)之間的差異向量????diff?=?point1?-?point2????#?計(jì)算并返回歐氏距離????dist?=?np.sqrt(np.sum(diff?**?2))????return?dist#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián)def?data_association(cost_matrix):????#?cost_matrix是一個(gè)m?x?n的矩陣,表示m個(gè)預(yù)測(cè)和n個(gè)觀測(cè)之間的代價(jià)(如距離或者負(fù)IoU)????#?返回一個(gè)長(zhǎng)度為m的向量,表示每個(gè)預(yù)測(cè)匹配的觀測(cè)的索引,如果沒(méi)有匹配,則為-1????#?使用scipy庫(kù)中的linear_sum_assignment函數(shù),求解最小化總代價(jià)的匹配方案????row_ind,?col_ind?=?linear_sum_assignment(cost_matrix)????#?初始化匹配結(jié)果為-1????matches?=?np.full(cost_matrix.shape[0],?-1)????#?將匹配方案賦值給匹配結(jié)果????matches[row_ind]?=?col_ind????return?matches
接下來(lái),我們需要定義一些評(píng)價(jià)指標(biāo)的計(jì)算函數(shù),如AOR,ACE,SR,PR,MOTA,MOTP,TL,TF,ISR等。我們已經(jīng)有了預(yù)測(cè)的3D邊界框和真實(shí)的3D邊界框的列表,以及每個(gè)邊界框的置信度得分。我們還需要定義一些閾值,如重疊比例閾值(iou_threshold),中心點(diǎn)距離閾值(dist_threshold),置信度得分閾值(score_threshold)等,這些閾值將在代碼中具體給出。
這里再次推薦「3D視覺(jué)工坊」新課程《面向自動(dòng)駕駛領(lǐng)域的3D點(diǎn)云目標(biāo)檢測(cè)全棧學(xué)習(xí)路線!(單模態(tài)+多模態(tài)/數(shù)據(jù)+代碼)》
#?計(jì)算平均重疊率(AOR)def?average_overlap_rate(pred_boxes,?gt_boxes):??? ?#?pred_boxes是一個(gè)p?x?7的矩陣,表示p個(gè)預(yù)測(cè)的3D邊界框? ????#?gt_boxes是一個(gè)g?x?7的矩陣,表示g個(gè)真實(shí)的3D邊界框?? ??????#?返回平均重疊率(AOR)值???? ??????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回0?? ????????if?pred_boxes.shape[0]?==?0?or?gt_boxes.shape[0]?==?0:?????? ??????????return?0.0????#?計(jì)算預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g??? ???????????iou_matrix?=?np.zeros((pred_boxes.shape[0],?gt_boxes.shape[0]))??? ????????????for?i?in?range(pred_boxes.shape[0]):?????? ??????????????for?j?in?range(gt_boxes.shape[0]):?????????? ????????????????iou_matrix[i][j]?=?iou_3d(pred_boxes[i],?gt_boxes[j])? ???????????????????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果?? ?????????????????????matches?=?data_association(-iou_matrix)?? ???????????????????????#?計(jì)算并返回平均重疊率(AOR)值? ???????????????????????ace?=?np.mean(dist_matrix[matches?!=?-1])? ??????????????????????????return?ace#?計(jì)算成功率(SR) ??????????????????????????def?success_rate(pred_boxes,?gt_boxes,?iou_threshold=0.5):??? ???????????????????????????#?pred_boxes是一個(gè)p?x?7的矩陣,表示p個(gè)預(yù)測(cè)的3D邊界框?? ?????????????????????????????#?gt_boxes是一個(gè)g?x?7的矩陣,表示g個(gè)真實(shí)的3D邊界框? ????????????????????????????????#?iou_threshold是一個(gè)浮點(diǎn)數(shù),表示重疊比例的閾值,默認(rèn)為0.5? ???????????????????????????????????#?返回成功率(SR)值?? ?????????????????????????????????????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回0?? ???????????????????????????????????????if?pred_boxes.shape[0]?==?0?or?gt_boxes.shape[0]?==?0: ???????????????????????????????????????????????return?0.0? ??????????????????????????????????????????????????#?計(jì)算預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g????iou_matrix?=?np.zeros((pred_boxes.shape[0],?gt_boxes.shape[0]))????for?i?in?range(pred_boxes.shape[0]):????????for?j?in?range(gt_boxes.shape[0]):????????????iou_matrix[i][j]?=?iou_3d(pred_boxes[i],?gt_boxes[j])????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????matches?=?data_association(-iou_matrix)????#?計(jì)算并返回成功率(SR)值????sr?=?np.sum(iou_matrix[matches?!=?-1]?>=?iou_threshold)?/?pred_boxes.shape[0]????return?sr#?計(jì)算精確率(PR)def?precision_rate(pred_boxes,?gt_boxes,?dist_threshold=1.0):????#?pred_boxes是一個(gè)p?x?7的矩陣,表示p個(gè)預(yù)測(cè)的3D邊界框????#?gt_boxes是一個(gè)g?x?7的矩陣,表示g個(gè)真實(shí)的3D邊界框????#?dist_threshold是一個(gè)浮點(diǎn)數(shù),表示中心點(diǎn)距離的閾值,默認(rèn)為1.0????#?返回精確率(PR)值????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回0????if?pred_boxes.shape[0]?==?0?or?gt_boxes.shape[0]?==?0:????????return?0.0????#?提取預(yù)測(cè)和真實(shí)邊界框的中心點(diǎn)坐標(biāo)????pred_centers?=?pred_boxes[:,?:3]????gt_centers?=?gt_boxes[:,?:3]????#?計(jì)算預(yù)測(cè)和真實(shí)邊界框之間的中心點(diǎn)距離矩陣,大小為p?x?g????dist_matrix?=?pairwise_distances(pred_centers,?gt_centers)????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????matches?=?data_association(dist_matrix)????#?計(jì)算并返回精確率(PR)值????pr?=?np.sum(dist_matrix[matches?!=?-1]?<=?dist_threshold)?/?pred_boxes.shape[0]????return?pr#?計(jì)算多目標(biāo)跟蹤精度(MOTA)def?multiple_object_tracking_accuracy(pred_boxes,?gt_boxes,?iou_threshold=0.5):????#?pred_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的預(yù)測(cè)的3D邊界框????#?gt_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的真實(shí)的3D邊界框????#?iou_threshold是一個(gè)浮點(diǎn)數(shù),表示重疊比例的閾值,默認(rèn)為0.5????#?返回多目標(biāo)跟蹤精度(MOTA)值????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回0????if?len(pred_boxes)?==?0?or?len(gt_boxes)?==?0:????????return?0.0????#?初始化漏檢數(shù)、誤檢數(shù)、ID切換數(shù)和總真實(shí)數(shù)為0????miss_count?=?0????false_count?=?0????switch_count?=?0????total_count?=?0????#?初始化上一時(shí)間步的匹配結(jié)果為空字典????prev_matches?=?{}????#?遍歷每個(gè)時(shí)間步????for?t?in?range(len(pred_boxes)):????????#?獲取當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框????????pred_box?=?pred_boxes[t]????????gt_box?=?gt_boxes[t]????????#?計(jì)算當(dāng)前時(shí)間步的真實(shí)邊界框的數(shù)量,并累加到總真實(shí)數(shù)中????????total_count?+=?gt_box.shape[0]????????#?如果當(dāng)前時(shí)間步?jīng)]有預(yù)測(cè)或真實(shí)邊界框,跳過(guò)該時(shí)間步????????if?pred_box.shape[0]?==?0?or?gt_box.shape[0]?==?0:????????????continue????????#?計(jì)算當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g????????iou_matrix?=?np.zeros((pred_box.shape[0],?gt_box.shape[0]))????????for?i?in?range(pred_box.shape[0]):????????????for?j?in?range(gt_box.shape[0]):????????????????iou_matrix[i][j]?=?iou_3d(pred_box[i],?gt_box[j])????????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????????matches?=?data_association(-iou_matrix)????????#?初始化當(dāng)前時(shí)間步的匹配結(jié)果為空字典????????curr_matches?=?{}????????#?遍歷每個(gè)預(yù)測(cè)邊界框????????for?i?in?range(pred_box.shape[0]):????????????#?如果沒(méi)有匹配的真實(shí)邊界框,或者重疊比例低于閾值,累加誤檢數(shù),并跳過(guò)該預(yù)測(cè)邊界框????????????if?matches[i]?==?-1?or?iou_matrix[i][matches[i]]?<?iou_threshold:????????????????false_count?+=?1????????????????continue????????????#?獲取匹配的真實(shí)邊界框的索引????????????j?=?matches[i]????????????#?如果上一時(shí)間步有匹配的真實(shí)邊界框,并且ID不同,累加ID切換數(shù)????????????if?j?in?prev_matches?and?prev_matches[j]?!=?i:????????????????switch_count?+=?1????????????#?將當(dāng)前的匹配結(jié)果保存到字典中????????????curr_matches[j]?=?i????????#?遍歷每個(gè)真實(shí)邊界框????????for?j?in?range(gt_box.shape[0]):????????????#?如果沒(méi)有匹配的預(yù)測(cè)邊界框,累加漏檢數(shù)????????????if?j?not?in?curr_matches:????????????????miss_count?+=?1????????#?更新上一時(shí)間步的匹配結(jié)果為當(dāng)前的匹配結(jié)果????????prev_matches?=?curr_matches????#?計(jì)算并返回多目標(biāo)跟蹤精度(MOTA)值????mota?=?1?-?(miss_count?+?false_count?+?switch_count)?/?total_count????return?mota#?計(jì)算多目標(biāo)跟蹤精確度(MOTP)def?multiple_object_tracking_precision(pred_boxes,?gt_boxes,?iou_threshold=0.5):????#?pred_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的預(yù)測(cè)的3D邊界框????#?gt_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的真實(shí)的3D邊界框????#?iou_threshold是一個(gè)浮點(diǎn)數(shù),表示重疊比例的閾值,默認(rèn)為0.5????#?返回多目標(biāo)跟蹤精確度(MOTP)值????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回0????if?len(pred_boxes)?==?0?or?len(gt_boxes)?==?0:????????return?0.0????#?初始化總匹配數(shù)和總重疊率為0????match_count?=?0????sum_iou?=?0.0????#?遍歷每個(gè)時(shí)間步????for?t?in?range(len(pred_boxes)):????????#?獲取當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框????????pred_box?=?pred_boxes[t]????????gt_box?=?gt_boxes[t]????????#?如果當(dāng)前時(shí)間步?jīng)]有預(yù)測(cè)或真實(shí)邊界框,跳過(guò)該時(shí)間步????????if?pred_box.shape[0]?==?0?or?gt_box.shape[0]?==?0:????????????continue????????#?計(jì)算當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g????????iou_matrix?=?np.zeros((pred_box.shape[0],?gt_box.shape[0]))????????for?i?in?range(pred_box.shape[0]):????????????for?j?in?range(gt_box.shape[0]):????????????????iou_matrix[i][j]?=?iou_3d(pred_box[i],?gt_box[j])????????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????????matches?=?data_association(-iou_matrix)????????#?遍歷每個(gè)預(yù)測(cè)邊界框????????for?i?in?range(pred_box.shape[0]):????????????#?如果沒(méi)有匹配的真實(shí)邊界框,或者重疊比例低于閾值,跳過(guò)該預(yù)測(cè)邊界框????????????if?matches[i]?==?-1?or?iou_matrix[i][matches[i]]?<?iou_threshold:????????????????continue????????????#?獲取匹配的真實(shí)邊界框的索引????????????j?=?matches[i]????????????#?累加匹配數(shù)和重疊率????????????match_count?+=?1????????????sum_iou?+=?iou_matrix[i][j]????#?計(jì)算并返回多目標(biāo)跟蹤精確度(MOTP)值????motp?=?sum_iou?/?match_count????return?motp#?計(jì)算跟蹤長(zhǎng)度(TL)def?track_length(pred_boxes,?gt_boxes,?iou_threshold=0.5):????#?pred_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的預(yù)測(cè)的3D邊界框????#?gt_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的真實(shí)的3D邊界框????#?iou_threshold是一個(gè)浮點(diǎn)數(shù),表示重疊比例的閾值,默認(rèn)為0.5????#?返回一個(gè)字典,鍵為真實(shí)目標(biāo)的ID,值為對(duì)應(yīng)的跟蹤長(zhǎng)度????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回空字典????if?len(pred_boxes)?==?0?or?len(gt_boxes)?==?0:????????return?{}????#?初始化跟蹤長(zhǎng)度字典為空字典????tl_dict?=?{}????#?遍歷每個(gè)時(shí)間步????for?t?in?range(len(pred_boxes)):????????#?獲取當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框????????pred_box?=?pred_boxes[t]????????gt_box?=?gt_boxes[t]????????#?如果當(dāng)前時(shí)間步?jīng)]有預(yù)測(cè)或真實(shí)邊界框,跳過(guò)該時(shí)間步????????if?pred_box.shape[0]?==?0?or?gt_box.shape[0]?==?0:????????????continue????????#?計(jì)算當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g????????iou_matrix?=?np.zeros((pred_box.shape[0],?gt_box.shape[0]))????????for?i?in?range(pred_box.shape[0]):????????????for?j?in?range(gt_box.shape[0]):????????????????iou_matrix[i][j]?=?iou_3d(pred_box[i],?gt_box[j])????????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????????matches?=?data_association(-iou_matrix)????????#?遍歷每個(gè)預(yù)測(cè)邊界框????????for?i?in?range(pred_box.shape[0]):????????????#?如果沒(méi)有匹配的真實(shí)邊界框,或者重疊比例低于閾值,跳過(guò)該預(yù)測(cè)邊界框????????????if?matches[i]?==?-1?or?iou_matrix[i][matches[i]]?<?iou_threshold:????????????????continue????????????#?獲取匹配的真實(shí)邊界框的索引????????????j?=?matches[i]????????????#?如果真實(shí)目標(biāo)的ID已經(jīng)在跟蹤長(zhǎng)度字典中,累加1????????????if?j?in?tl_dict:????????????????tl_dict[j]?+=?1????????????#?否則,初始化為1????????????else:????????????????tl_dict[j]?=?1????#?返回跟蹤長(zhǎng)度字典????return?tl_dict#?計(jì)算跟蹤片段(TF)def?track_fragment(pred_boxes,?gt_boxes,?iou_threshold=0.5):????#?pred_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的預(yù)測(cè)的3D邊界框????#?gt_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的真實(shí)的3D邊界框????#?iou_threshold是一個(gè)浮點(diǎn)數(shù),表示重疊比例的閾值,默認(rèn)為0.5????#?返回一個(gè)字典,鍵為真實(shí)目標(biāo)的ID,值為對(duì)應(yīng)的跟蹤片段數(shù)????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回空字典????if?len(pred_boxes)?==?0?or?len(gt_boxes)?==?0:????????return?{}????#?初始化跟蹤片段字典為空字典????tf_dict?=?{}????#?初始化上一時(shí)間步的匹配結(jié)果為空字典????prev_matches?=?{}????#?遍歷每個(gè)時(shí)間步????for?t?in?range(len(pred_boxes)):????????#?獲取當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框????????pred_box?=?pred_boxes[t]????????gt_box?=?gt_boxes[t]????????#?如果當(dāng)前時(shí)間步?jīng)]有預(yù)測(cè)或真實(shí)邊界框,跳過(guò)該時(shí)間步????????if?pred_box.shape[0]?==?0?or?gt_box.shape[0]?==?0:????????????continue????????#?計(jì)算當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g????????iou_matrix?=?np.zeros((pred_box.shape[0],?gt_box.shape[0]))????????for?i?in?range(pred_box.shape[0]):????????????for?j?in?range(gt_box.shape[0]):????????????????iou_matrix[i][j]?=?iou_3d(pred_box[i],?gt_box[j])????????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????????matches?=?data_association(-iou_matrix)????????#?初始化當(dāng)前時(shí)間步的匹配結(jié)果為空字典????????curr_matches?=?{}????????#?遍歷每個(gè)預(yù)測(cè)邊界框????????for?i?in?range(pred_box.shape[0]):????????????#?如果沒(méi)有匹配的真實(shí)邊界框,或者重疊比例低于閾值,跳過(guò)該預(yù)測(cè)邊界框????????????if?matches[i]?==?-1?or?iou_matrix[i][matches[i]]?<?iou_threshold:????????????????continue????????????#?獲取匹配的真實(shí)邊界框的索引????????????j?=?matches[i]????????????#?將當(dāng)前的匹配結(jié)果保存到字典中????????????curr_matches[j]?=?i????????????#?如果真實(shí)目標(biāo)的ID已經(jīng)在跟蹤片段字典中,且上一時(shí)間步?jīng)]有匹配該目標(biāo),累加1????????????if?j?in?tf_dict?and?j?not?in?prev_matches:????????????????tf_dict[j]?+=?1????????????#?否則,初始化為1????????????elif?j?not?in?tf_dict:????????????????tf_dict[j]?=?1????????#?更新上一時(shí)間步的匹配結(jié)果為當(dāng)前的匹配結(jié)果????????prev_matches?=?curr_matches????#?返回跟蹤片段字典????return?tf_dict#?計(jì)算ID切換率(ISR)def?id_switch_rate(pred_boxes,?gt_boxes,?iou_threshold=0.5):????#?pred_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的預(yù)測(cè)的3D邊界框????#?gt_boxes是一個(gè)列表,長(zhǎng)度為t,表示t個(gè)時(shí)間步的真實(shí)的3D邊界框????#?iou_threshold是一個(gè)浮點(diǎn)數(shù),表示重疊比例的閾值,默認(rèn)為0.5????#?返回一個(gè)字典,鍵為真實(shí)目標(biāo)的ID,值為對(duì)應(yīng)的ID切換次數(shù)????#?如果沒(méi)有預(yù)測(cè)或真實(shí)邊界框,返回空字典????if?len(pred_boxes)?==?0?or?len(gt_boxes)?==?0:????????return?{}????#?初始化ID切換率字典為空字典????isr_dict?=?{}????#?初始化上一時(shí)間步的匹配結(jié)果為空字典????prev_matches?=?{}????#?遍歷每個(gè)時(shí)間步????for?t?in?range(len(pred_boxes)):????????#?獲取當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框????????pred_box?=?pred_boxes[t]????????gt_box?=?gt_boxes[t]????????#?如果當(dāng)前時(shí)間步?jīng)]有預(yù)測(cè)或真實(shí)邊界框,跳過(guò)該時(shí)間步????????if?pred_box.shape[0]?==?0?or?gt_box.shape[0]?==?0:????????????continue????????#?計(jì)算當(dāng)前時(shí)間步的預(yù)測(cè)和真實(shí)邊界框之間的重疊比例矩陣,大小為p?x?g????????iou_matrix?=?np.zeros((pred_box.shape[0],?gt_box.shape[0]))????????for?i?in?range(pred_box.shape[0]):????????????for?j?in?range(gt_box.shape[0]):????????????????iou_matrix[i][j]?=?iou_3d(pred_box[i],?gt_box[j])????????#?使用匈牙利算法進(jìn)行數(shù)據(jù)關(guān)聯(lián),得到匹配結(jié)果????????matches?=?data_association(-iou_matrix)????????#?初始化當(dāng)前時(shí)間步的匹配結(jié)果為空字典????????curr_matches?=?{}????????#?遍歷每個(gè)預(yù)測(cè)邊界框????????for?i?in?range(pred_box.shape[0]):????????????#?如果沒(méi)有匹配的真實(shí)邊界框,或者重疊比例低于閾值,跳過(guò)該預(yù)測(cè)邊界框????????????if?matches[i]?==?-1?or?iou_matrix[i][matches[i]]?<?iou_threshold:????????????????continue????????????#?獲取匹配的真實(shí)邊界框的索引????????????j?=?matches[i]????????????#?將當(dāng)前的匹配結(jié)果保存到字典中????????????curr_matches[j]?=?i????????????#?如果上一時(shí)間步有匹配的真實(shí)邊界框,并且ID不同,累加1????????????if?j?in?prev_matches?and?prev_matches[j]?!=?i:????????????????#?如果真實(shí)目標(biāo)的ID已經(jīng)在ID切換率字典中,累加1????????????????if?j?in?isr_dict:????????????????????isr_dict[j]?+=?1????????????????#?否則,初始化為1????????????????else:????????????????????isr_dict[j]?=?1????????#?更新上一時(shí)間步的匹配結(jié)果為當(dāng)前的匹配結(jié)果????????prev_matches?=?curr_matches????#?返回ID切換率字典????return?isr_dict
以上就是我?guī)痛蠹铱偨Y(jié)的3D點(diǎn)云目標(biāo)跟蹤中常見(jiàn)的評(píng)價(jià)指標(biāo)和代碼詳解,希望可以幫助到大家。
目前工坊已經(jīng)建立了3D視覺(jué)方向多個(gè)社群,包括SLAM、工業(yè)3D視覺(jué)、自動(dòng)駕駛方向,細(xì)分群包括:[工業(yè)方向]三維點(diǎn)云、結(jié)構(gòu)光、機(jī)械臂、缺陷檢測(cè)、三維測(cè)量、TOF、相機(jī)標(biāo)定、綜合群;[SLAM方向]多傳感器融合、ORB-SLAM、激光SLAM、機(jī)器人導(dǎo)航、RTK|GPS|UWB等傳感器交流群、SLAM綜合討論群;[自動(dòng)駕駛方向]深度估計(jì)、Transformer、毫米波|激光雷達(dá)|視覺(jué)攝像頭傳感器討論群、多傳感器標(biāo)定、自動(dòng)駕駛綜合群等。[三維重建方向]NeRF、colmap、OpenMVS等。除了這些,還有求職、硬件選型、視覺(jué)產(chǎn)品落地等交流群。大家可以添加小助理微信:?dddvisiona,備注:加群+方向+學(xué)校|公司, 小助理會(huì)拉你入群。