PointCore: Efficient Unsupervised Point Cloud Anomaly Detector Using Local-Global Features
1銆丅ackground
褰撳墠鐨勭偣浜戝紓甯告娴嬪櫒鍙互鍒嗕负涓ょ被锛?/p>
锛?锛夊熀浜庨噸寤虹殑鏂规硶锛岄€氳繃鑷姩缂栫爜鍣ㄩ噸寤鸿緭鍏ョ偣浜戞暟鎹紝骞堕€氳繃姣旇緝鍘熷鏁版嵁鍜岄噸寤烘暟鎹箣闂寸殑鍋忓樊鏉ヨ瘑鍒紓甯搞€傜劧鑰岋紝杩欎簺鏂规硶瀵圭偣浜戠殑鍒嗚鲸鐜囨晱鎰燂紝瀵艰嚧鎺ㄧ悊閫熷害鎱㈠拰绮惧害宸€?/p>
锛?锛夊熀浜庤蹇嗗簱鐨勬柟娉曪紝璁板繂搴撴湁鍔╀簬瀛樺偍浠h〃鎬х壒寰侊紝闅愬紡鏋勫缓姝e父鍒嗗竷骞跺鎵惧垎甯冨鐨勭己闄枫€備笌鍓嶈€呯浉姣旓紝鐩存帴浣跨敤棰勮缁冪殑鐗瑰緛鎻愬彇鍣ㄦ瀯寤鸿蹇嗗簱鍏锋湁璁粌閫熷害蹇笖涓嶅彈鐐逛簯鍒嗚鲸鐜囧奖鍝嶇殑浼樼偣銆傛澶栵紝鐜版湁鐨勭偣浜戝紓甯告娴嬪櫒閫氬父閲囩敤澶氫釜鐗瑰緛璁板繂搴撴潵鍏呭垎淇濈暀灞€閮ㄥ拰鍏ㄥ眬琛ㄧず锛岃繖瀵艰嚧浜嗚绠楀鏉傚害楂樺拰鐗瑰緛涓嶅尮閰嶇殑闂銆?/p>
涓轰簡瑙e喅涓婅堪闂锛屾彁鍑轰簡涓€涓熀浜庤仈鍚堝眬閮?鍏ㄥ眬鐗瑰緛鐨勬棤鐩戠潱鐐逛簯寮傚父妫€娴嬫鏋讹紝绉颁负PointCore銆傚叿浣撴潵璇达紝鎬荤粨濡備笅锛?/p>
锛?锛塒ointCore鍙渶瑕佷竴涓蹇嗗簱鏉ュ瓨鍌ㄥ眬閮?鍏ㄥ眬琛ㄧず锛屽苟涓鸿繖浜涘眬閮?鍏ㄥ眬鐗瑰緛鍒嗛厤涓嶅悓鐨勪紭鍏堢骇锛屼互鍑忓皯鎺ㄧ悊杩囩▼涓殑璁$畻鎴愭湰鍜屼笉鍖归厤骞叉壈銆?/p>
锛?锛夋彁鍑轰簡涓€绉嶅熀浜庢帓鍚嶇殑褰掍竴鍖栨柟娉曪紝浠ユ秷闄ゅ悇绉嶅紓甯稿垎鏁颁箣闂寸殑鍒嗗竷宸紓锛屽苟搴旂敤鐐瑰骞抽潰杩唬鏈€杩戠偣锛坧oint-plane ICP锛夌畻娉曞鐐逛簯娉ㄥ唽缁撴灉杩涜灞€閮ㄤ紭鍖栵紝浠ュ疄鐜扮ǔ鍋ョ殑鍐崇瓥銆?/p>
2銆丮ethod
PointCore 绠楁硶娴佺▼锛?/p>
- 鍏ㄥ眬娉ㄥ唽锛?
灏嗘墍鏈夌偣浜戞暟鎹粺涓€鍒颁竴涓叡鍚岀殑鍧愭爣绯荤粺涓€?/code>
- 閫夋嫨鍙傝€冪偣浜戯細棣栧厛閫夋嫨涓€涓偣浜戜綔涓哄弬鑰冿紝鍏朵粬鐐逛簯灏嗕笌瀹冭繘琛屽姣斻€?/li>
- 璁$畻鏃嬭浆鍜屽钩绉伙細浣跨敤绠楁硶锛堝杩唬鏈€杩戠偣绠楁硶鎴栫壒寰佸尮閰嶇畻娉曪級璁$畻鍑哄叾浠栫偣浜戠浉瀵逛簬鍙傝€冪偣浜戠殑鏃嬭浆鐭╅樀鍜屽钩绉诲悜閲忋€?/li>
- 搴旂敤鍙樻崲锛氬皢杩欎簺鍙樻崲搴旂敤鍒板叾浠栫偣浜戜笂锛屼娇瀹冧滑鍦ㄧ┖闂翠腑鐨勪綅缃拰鏂瑰悜涓庡弬鑰冪偣浜戜竴鑷淬€?/li>
- 灞€閮ㄤ紭鍖?/strong>锛?
鍦ㄥ叏灞€娉ㄥ唽鐨勫熀纭€涓婅繘琛岋紝瀹冨鐐逛簯杩涜鏇寸簿缁嗙殑璋冩暣
锛岀‘淇濈偣浜戠殑灞€閮ㄧ壒寰佽兘澶熺簿纭榻愩€?- 閫夋嫨灞€閮ㄧ壒寰佺偣锛氬湪鐐逛簯涓€夋嫨涓€浜涘叿鏈夋槑鏄剧壒寰佺殑鐐癸紝濡傝鐐广€佽竟缂樼偣绛夈€?/li>
- 璁$畻灞€閮ㄥ彉鎹細璁$畻杩欎簺鐗瑰緛鐐逛箣闂寸殑璺濈鍜屾柟鍚戯紝纭畾闇€瑕佽繘琛岀殑寰皬鏃嬭浆鍜屽钩绉伙紝浠ヤ娇瀹冧滑鏇村ソ鍦板榻愩€?/li>
- 杩唬浼樺寲锛氶€氳繃杩唬杩囩▼涓嶆柇璋冩暣杩欎簺灞€閮ㄧ壒寰佺偣鐨勪綅缃紝鐩村埌杈惧埌棰勫畾鐨勭簿搴︺€?/li>
- 鐗瑰緛鎻愬彇
- 浣跨敤棰勮缁冪殑PointMAE锛堢偣鑷紪鐮佸櫒锛夌壒寰佹彁鍙栧櫒锛屼粠鐐逛簯涓彁鍙朠ointMAE鐗瑰緛銆?/li>
- 鏋勫缓璁板繂搴?
- 灏嗙偣浜戠殑鍧愭爣鍜屾彁鍙栫殑PointMAE鐗瑰緛缁撳悎璧锋潵锛屽舰鎴愯蹇嗗簱銆傝繖涓蹇嗗簱鐢ㄦ潵瀛樺偍姝e父鐐逛簯鐨勭壒寰侊紝浠ヤ究鍚庣画姣旇緝銆?/li>
- 鎺ㄧ悊妯″潡
- 褰撴湁鏂扮殑鐐逛簯鏁版嵁闇€瑕佹娴嬫椂锛屾垜浠悓鏍锋彁鍙栬繖浜涚偣浜戠殑鍧愭爣鍜孭ointMAE鐗瑰緛銆?/li>
- 鐒跺悗锛岃绠楁柊鐐逛簯涓瘡涓偣涓庤蹇嗗簱涓瓨鍌ㄧ殑姝e父鐐逛簯鐗瑰緛涔嬮棿鐨勫樊寮傘€?/li>
- 璁$畻寮傚父鍒嗘暟锛氶€氳繃姣旇緝鏂扮偣浜戜笌璁板繂搴撲腑鐨勭壒寰佸樊寮傦紝璁$畻姣忎釜鐐圭殑寮傚父鍒嗘暟銆傝繖涓垎鏁拌〃绀鸿鐐逛笌姝e父鐐逛簯鐨勫樊寮傜▼搴︺€?/li>
- 瀹氫綅寮傚父鍖哄煙锛氭牴鎹绠楀嚭鐨勫紓甯稿垎鏁帮紝鎴戜滑鍙互纭畾鏂扮偣浜戜腑鍝簺鍖哄煙鍙兘鏄紓甯哥殑銆?/li>
pseudo-code
# 瀹氫箟鍏ㄥ眬鍜屽眬閮ㄦ敞鍐屽嚱鏁?/span>
function register_point_clouds(point_clouds):
for each point_cloud in point_clouds:
global_registration(point_cloud)
local_optimization(point_cloud)
return registered_point_clouds
# 鍏ㄥ眬娉ㄥ唽
function global_registration(point_cloud):
# 浣跨敤FPFH鐗瑰緛鎻忚堪绗﹀拰RANSAC绠楁硶杩涜鍏ㄥ眬娉ㄥ唽
return transformed_point_cloud
# 灞€閮ㄤ紭鍖?/span>
function local_optimization(point_cloud):
# 浣跨敤鐐?骞抽潰ICP绠楁硶杩涜灞€閮ㄤ紭鍖?/span>
return optimized_point_cloud
# 瀹氫箟鐗瑰緛鎻愬彇鍑芥暟
function extract_features(registered_point_clouds):
features = []
for point_cloud in registered_point_clouds:
coordinates = sample_coordinates(point_cloud)
pointMAE_features = pointMAE_extractor(coordinates)
features.append((coordinates, pointMAE_features))
return features
# 鍧愭爣閲囨牱
function sample_coordinates(point_cloud):
# 浣跨敤璐┆绠楁硶瀵圭偣浜戣繘琛屼笅閲囨牱
return sampled_coordinates
# 浣跨敤PointMAE鎻愬彇鐗瑰緛
function pointMAE_extractor(coordinates):
# 浣跨敤棰勮缁冪殑PointMAE妯″瀷鎻愬彇鐗瑰緛
return extracted_features
# 瀹氫箟鎺ㄧ悊鍜屽紓甯稿垎鏁拌绠楀嚱鏁?/span>
function compute_anomaly_scores(features, test_point_cloud):
memory_bank = construct_memory_bank(features)
anomaly_scores = []
for point in test_point_cloud:
score = calculate_anomaly_score(memory_bank, point)
anomaly_scores.append(score)
return anomaly_scores
# 鏋勫缓璁板繂搴?/span>
function construct_memory_bank(features):
# 灏嗗潗鏍囧拰PointMAE鐗瑰緛缁撳悎锛屽舰鎴愯蹇嗗簱
return memory_bank
# 璁$畻寮傚父鍒嗘暟
function calculate_anomaly_score(memory_bank, test_point):
# 浣跨敤璁板繂搴撲腑鐨勬暟鎹绠楁祴璇曠偣鐨勫紓甯稿垎鏁?/span>
return anomaly_score
# 涓绘祦绋?/span>
function main(train_point_clouds, test_point_cloud):
registered_train = register_point_clouds(train_point_clouds)
features = extract_features(registered_train)
memory_bank = construct_memory_bank(features)
anomaly_scores = compute_anomaly_scores(features, test_point_cloud)
return anomaly_scores
3銆丒xperiments
馃悅馃悗銆傘€傘€?/p>
4銆丆onclusion
鎻愬嚭浜?鍩轰簬鍗曚釜璁板繂搴撶殑灞€閮?鍏ㄥ眬鐗瑰緛鏉ュ瓨鍌ㄨ緭鍏ョ偣浜戠殑澶氬昂搴︿俊鎭?/code> 鐨勬棤鐩戠潱鐐逛簯寮傚父妫€娴嬪櫒 PointCore