diff --git a/frame_2D_alg/vectorize_edge_blob/agg_recursion.py b/frame_2D_alg/vectorize_edge_blob/agg_recursion.py index 2c305de0d..b469b6b02 100644 --- a/frame_2D_alg/vectorize_edge_blob/agg_recursion.py +++ b/frame_2D_alg/vectorize_edge_blob/agg_recursion.py @@ -21,7 +21,7 @@ def cluster_eval(frame, N_, fd): G_ = cluster_N_(frame, pL_, fd) # optionally divisive clustering frame.subG_ = G_ if len(G_) > ave_L: - med_cluster_(frame) # alternating medoid clustering + get_exemplar_(frame) # may call medoid clustering ''' cross-comp converted edges, then GGs, GGGs., interlaced connectivity clustering and exemplar selection ''' @@ -108,7 +108,7 @@ def cluster_N_(root, L_, fd, nest=1): # top-down segment L_ by >ave ratio of L. Med_cluster may be extended, but only its exemplar node (with max m to medoid) will be a sample for next cross-comp. Other nodes interactions can be predicted from the exemplar, they are supposed to be the same type of objects. ''' -def med_cluster_(frame): +def get_exemplar_(frame): def comp_cN(_N, N): # compute match without new derivatives: relation to the medoid is not directional @@ -123,8 +123,8 @@ def comp_cN(_N, N): # compute match without new derivatives: relation to the me def medoid(N_): # sum and average nodes - N = CG(root_=[None]) - for n in N_: + N = CG() + for n, m in N_: N.n += n.n; N.rng = n.rng; N.aRad += n.aRad N.box = extend_box(N.box, n.box) N.latuple += n.latuple; N.mdLay += n.mdLay @@ -136,6 +136,8 @@ def medoid(N_): # sum and average nodes def xcomp_(N_): # initial global cross-comp + for g in N_: # setattr + g.M = 0 for _G, G in combinations(N_, r=2): rn = _G.n/G.n if rn > ave_rn: continue # scope disparity @@ -143,19 +145,18 @@ def xcomp_(N_): # initial global cross-comp vM = M - ave for _g,g in (_G,G),(G,_G): if vM > 0: - g.perim.add(_g) # loose match + g.perim.add((_g,M)) # loose match if vM > ave: g.crim.add((_g,M)) # strict match g.M += M - def get_exemplar_(N_): # select Ns with M > ave * Mr + def prune_overlap(N_): # select Ns with M > ave * Mr exemplar_ = [] for N in N_: - for _N, M in N.crim: - if N.M >_N.M: _N.M -= M - else: N.M -= M - # exclusive representation, or incr N.Mr? + for _N,m in N.crim: + if N.M < _N.M: + N.M -= m # exclusive representation, vs. N.Mr+=1? if N.M > ave: exemplar_ += [N] @@ -163,16 +164,21 @@ def get_exemplar_(N_): # select Ns with M > ave * Mr def refine_(exemplar): _node_, _peri_, _M = exemplar.crim, exemplar.perim, exemplar.M - dM = ave + 1 while dM > ave: node_, peri_, M = set(), set(), 0 mN = medoid(_node_) - for _N,_m in _peri_: + for ref in _peri_: + _N,_m = ref m = comp_cN(mN,_N) - if M > ave: - peri_.add((_N,m)) - if M > ave*2: node_.add((_N,m)) + M += m + if m > ave: + peri_.add((_N,_m)) + if m > ave * 20: + node_.add((_N,_m)) + for _ref in _N.crim: # crims are exclusive + if _ref is ref: + _N.crim.remove(ref); _N.M -= _m; break dM = M - _M _node_,_peri_,_M = node_,peri_,M @@ -180,14 +186,17 @@ def refine_(exemplar): N_ = frame.subG_ # should be complemented graphs: m-type core + d-type contour for N in N_: - N.perim = set(); N.crim = set(); N.root_ += [frame] + N.perim = set(); N.crim = set(); N.root_ += [frame]; N.M = 0 xcomp_(N_) - exemplar_ = get_exemplar_(N_) # select strong Ns + exemplar_ = prune_overlap(N_) # select strong Ns + subG_ = set() for N in exemplar_: - if N.M > ave * 10: # tentative, else keep N.crim - refine_(N) # N.crim = N.perim clustered by N.crim medoid - frame.exemplar_ = exemplar_ - if len(frame.exemplar_) > ave_L: + if N.M > ave * 10: # else keep N.crim + refine_(N) # N.crim = N.perim exclusively clustered by N.crim medoid + if N.M: # has crim, pruned in refine_ + subG_.add(N) + frame.subG_ = list(subG_) + if len(frame.subG_) > ave_L: agg_cluster_(frame) # alternating connectivity clustering per exemplar, more selective @@ -198,5 +207,4 @@ def refine_(exemplar): intra_blob_root(frame) vectorize_root(frame) if frame.subG_: # converted edges - # start from medoid clustering because edges are connectivity-clustered - med_cluster_(frame) # starts alternating agg_recursion \ No newline at end of file + get_exemplar_(frame) # selects connectivity-clustered edges for agg_cluster_ \ No newline at end of file diff --git a/frame_2D_alg/vectorize_edge_blob/trace_edge.py b/frame_2D_alg/vectorize_edge_blob/trace_edge.py index 427cb285b..a98954270 100644 --- a/frame_2D_alg/vectorize_edge_blob/trace_edge.py +++ b/frame_2D_alg/vectorize_edge_blob/trace_edge.py @@ -222,11 +222,7 @@ def vectorize_root(frame): for N in edge.node_: # no comp node_, link_ | PPd_ for now md_,Et,n = N[3] if isinstance(N,list) else N.mdLay # N is CP if any(md_) and Et[0] > ave * Et[2]: # convert PP|P to G: - if isinstance(N,list): - root_,P_,link_,(md_,Et,n), lat, A, S, area, box, [y,x], n = N # PPt - else: # single CP - root_=edge; P_=[N]; link_=[]; md_,Et,n = N.mdLay; lat=N.latuple; [y,x]=N.yx; n=N.n - box = [y, x-len(N.dert_), y,x] + root_,P_,link_,(md_,Et,n), lat, A, S, area, box, [y,x], n = N # PPt PP = CG(fd=0, root_=[root_], node_=P_,link_=link_,mdLay=np.array([md_,Et,n],dtype=object),latuple=lat, box=box,yx=[y,x],n=n) y0,x0,yn,xn = box PP.aRad = np.hypot(*np.subtract(PP.yx,(yn,xn)))