采用类似连通域的两遍遍历法,聚合mark
使用方法:
1、初始化聚合池
2、不停往聚合池中添加两两匹配关系
3、输出聚合结果
# -- coding: utf-8 --
import os
import glob
import sys
import cv2
import shutil
import numpy as np
import random
class AggregatePool(object):
def __init__(self):
self.markid2pmarkid = {}
self.pmarkid2markid = {}
self.group_id = 0
self.group_id_pairs = []
def append(self, qmarkid, bmarkid, aggregate):
if not aggregate: # 不可差
if qmarkid not in self.markid2pmarkid:
self.markid2pmarkid[qmarkid] = self.group_id
self.group_id += 1
if bmarkid not in self.markid2pmarkid:
self.markid2pmarkid[bmarkid] = self.group_id
self.group_id += 1
else: # 可差
if qmarkid in self.markid2pmarkid and bmarkid in self.markid2pmarkid:
self.group_id_pairs.append((min(self.markid2pmarkid[qmarkid], self.markid2pmarkid[bmarkid]),
max(self.markid2pmarkid[qmarkid], self.markid2pmarkid[bmarkid])))
if qmarkid in self.markid2pmarkid and bmarkid not in self.markid2pmarkid:
self.markid2pmarkid[bmarkid] = self.markid2pmarkid[qmarkid]
if qmarkid not in self.markid2pmarkid and bmarkid in self.markid2pmarkid:
self.markid2pmarkid[qmarkid] = self.markid2pmarkid[bmarkid]
if qmarkid not in self.markid2pmarkid and bmarkid not in self.markid2pmarkid:
self.markid2pmarkid[qmarkid] = self.group_id
self.markid2pmarkid[bmarkid] = self.group_id
self.group_id += 1
def aggregate(self):
set_list = []
for id1, id2 in self.group_id_pairs:
exist = False
for s in set_list:
if id1 in s or id2 in s:
s.add(id1)
s.add(id2)
exist = True
if not exist:
news = {id1, id2}
set_list.append(news)
idmap = {}
for s in set_list:
mins = min(s)
for id in s:
idmap[id] = mins
# 刷新group-id
for markid in self.markid2pmarkid:
oldid = self.markid2pmarkid[markid]
newid = idmap[oldid]
self.markid2pmarkid[markid] = newid
# 聚类
for markid in self.markid2pmarkid:
gid = self.markid2pmarkid[markid]
if gid not in self.pmarkid2markid:
self.pmarkid2markid[gid] = []
self.pmarkid2markid[gid].append(markid)
# 可视化
for gid in self.pmarkid2markid:
print(gid, "====================")
for mark in self.pmarkid2markid[gid]:
print(mark)
if __name__ == '__main__':
all_marks = []
# 创造100个待聚合的实例
for i in range(100):
singleid = random.randint(10000, 99999)
gid = random.randint(50, 55)
s = str(singleid)+"."+str(gid)
all_marks.append(s)
agg = AggregatePool() # 初始化聚合池
for i, qm in enumerate(all_marks):
for j, bm in enumerate(all_marks):
if i == j:
continue
else:
if qm.split(".")[-1] == bm.split(".")[-1]: # 判断两两是否可聚
agg.append(qm, bm, True) # 添加聚合关系
else:
agg.append(qm, bm, False) # 添加聚合关系
agg.aggregate() # 输出聚合结果