annotation_dashboard/commit
first stab at region merging
author | Jacco van Ossenbruggen |
---|---|
Mon May 26 22:07:56 2014 +0300 | |
committer | Jacco van Ossenbruggen |
Mon May 26 22:07:56 2014 +0300 | |
commit | e6590b7b4de86b00715891df0e733425fabf3bf1 |
tree | 14fafc2e9bf91fddcdc63198c52c87291a02c4b3 |
parent | efa8330fb191dcf059a33071e25a163f6cd07be1 |
Diff style: patch stat
diff --git a/applications/dashboard.pl b/applications/dashboard.pl index 44b41fc..10c5485 100644 --- a/applications/dashboard.pl +++ b/applications/dashboard.pl @@ -24,6 +24,7 @@ % from this pack: :- use_module(api(dashboard_api)). :- use_module(library(dashboard_util)). +:- use_module(library(region_merge)). :- http_handler(cliopatria(annotate/dashboard/home), http_dashboard_home, []). :- http_handler(cliopatria(annotate/dashboard/user), http_dashboard_user, []). diff --git a/lib/region_merge.pl b/lib/region_merge.pl new file mode 100644 index 0000000..eb384bd --- /dev/null +++ b/lib/region_merge.pl @@ -0,0 +1,97 @@ +:- module(ad_region_merge, + [ region_merge/3 + ]). + +:- use_module(library(oa_annotation)). +:- use_module(library(settings)). + +:- setting(minimum_overlap, float, 0.3, 'minimum overlapping ratio'). + +region_merge(Target, Merged, Options) :- + findall(A, rdf_get_annotation_by_tfa(Target, _,_,_, A), As), + reset_gensym(sid), + region_merge(As, m{none:[]}, Merged, Options), + dict_pairs(Merged, m, Pairs), + length(Pairs, Lout), + length(As, Lin), + debug(merge, '~n# merged regions: ~d~n# input regions: ~d', [Lout,Lin]). + + +region_merge([], Result, Result, _Options):- !. +region_merge([H|T], Accum, Result, Options) :- + dict_create(D, an, H), + overlapping_annotation(D, Accum, NewAccum), + !, + region_merge(T, NewAccum, Result, Options). +region_merge([H|T], Accum, Result, Options) :- + Accum.put(none, [H|Accum.none]), + region_merge(T, [Accum], Result, Options). + +overlapping_annotation(A, Accum, New) :- + T = A.hasTarget, + S = T.get('hasSelector'), + None = best{overlap:0, key:none}, + best_overlapping_selector(S, None, Accum, Best), + ( insufficent_overlap(S, Best) + -> gensym(sid, Tid), + debug(merge, 'Creating new ~w for ~w', [Tid, S.value]), + New = Accum.put(Tid,_{children:[A], hasSelector:S}) + ; merge_selectors(A, S, Best, Accum, New) + ). + +insufficent_overlap(_S, Best) :- + Best.overlap == 0, !. +insufficent_overlap(S, B) :- + AreaS is S.w * S.h, + AreaB is B.hasSelector.w * B.hasSelector.h, + RatioS is B.overlap/AreaS, + RatioB is B.overlap/AreaB, + setting(minimum_overlap, Min), + ( RatioS < Min + ; RatioB < Min + ), + debug(merge, 'insuf. overlap ~3f ~3f', [RatioS, RatioB]). + +merge_selectors(A, S, B, Accum, New) :- + debug(merge, 'Merging: ~w into ~w, overlap ~3f', + [S.value, B.key, B.overlap]), + AccumChildren = Accum.get(B.key).children, + X is min(S.x, B.hasSelector.x), W is max(S.w, B.hasSelector.w), + Y is min(S.y, B.hasSelector.y) ,H is max(S.h, B.hasSelector.h), + NewSelector = selector{x:X, y:Y, w:W, h:H}, + New = Accum + .put(B.key/children, [A|AccumChildren]) + .put(B.key/hasSelector, NewSelector). + +best_overlapping_selector(S, BestSoFar, AccumDict, Best) :- + dict_pairs(AccumDict, m, AccumPairs), + best_overlapping_selector_(S, BestSoFar, AccumPairs,Best). + + +best_overlapping_selector_(_,Best, [], Best):- !. +best_overlapping_selector_(S, BestSoFar, [H|T], Best) :- + H=Key-Hdict, + ( Key = none + -> best_overlapping_selector_(S, BestSoFar, T, Best) + ; HS=Hdict.hasSelector, + selector_overlap(S, HS, Overlap), + ( Overlap > BestSoFar.overlap + -> NewBest = best{overlap:Overlap, key:Key, hasSelector:HS}, + best_overlapping_selector_(S, NewBest, T, Best) + ; best_overlapping_selector_(S, BestSoFar, T, Best) + ) + ). + +% A.x1_______________AX2 +% B.x1_______________BX2 +selector_overlap(A, B, Overlap) :- + AX2 is A.x + A.w, AY2 is A.y + A.h, + BX2 is B.x + B.w, BY2 is B.y + B.w, + OX is min(AX2, BX2) - max(A.x, B.x), + OY is min(AY2, BY2) - max(A.y, B.y), + Overlap is OX * OY. + + + + +