(1) add_new_node(G, node) : add "node" to graph "G" (2) add_new_edge(G, node_a, node_b) : add edge "node_a--node_b" to graph "G" (3) exceed_thre(x, y, thre) : Check if difference between "x" and "y" exceed threshold "thre" (4) key_exist(d, k) : Check if key "k' exists in dictionary
(LDI, config, image, remove_conflict_ordinal, spdb=False)
| 383 | return mesh |
| 384 | |
| 385 | def group_edges(LDI, config, image, remove_conflict_ordinal, spdb=False): |
| 386 | |
| 387 | ''' |
| 388 | (1) add_new_node(G, node) : add "node" to graph "G" |
| 389 | (2) add_new_edge(G, node_a, node_b) : add edge "node_a--node_b" to graph "G" |
| 390 | (3) exceed_thre(x, y, thre) : Check if difference between "x" and "y" exceed threshold "thre" |
| 391 | (4) key_exist(d, k) : Check if key "k' exists in dictionary "d" |
| 392 | (5) comm_opp_bg(G, x, y) : Check if node "x" and "y" in graph "G" treat the same opposite node as background |
| 393 | (6) comm_opp_fg(G, x, y) : Check if node "x" and "y" in graph "G" treat the same opposite node as foreground |
| 394 | ''' |
| 395 | add_new_node = lambda G, node: None if G.has_node(node) else G.add_node(node) |
| 396 | add_new_edge = lambda G, node_a, node_b: None if G.has_edge(node_a, node_b) else G.add_edge(node_a, node_b) |
| 397 | exceed_thre = lambda x, y, thre: (abs(x) - abs(y)) > thre |
| 398 | key_exist = lambda d, k: d.get(k) is not None |
| 399 | comm_opp_bg = lambda G, x, y: key_exist(G.nodes[x], 'far') and key_exist(G.nodes[y], 'far') and \ |
| 400 | not(set(G.nodes[x]['far']).isdisjoint(set(G.nodes[y]['far']))) |
| 401 | comm_opp_fg = lambda G, x, y: key_exist(G.nodes[x], 'near') and key_exist(G.nodes[y], 'near') and \ |
| 402 | not(set(G.nodes[x]['near']).isdisjoint(set(G.nodes[y]['near']))) |
| 403 | discont_graph = netx.Graph() |
| 404 | ''' |
| 405 | (A) Skip the pixel at image boundary, we don't want to deal with them. |
| 406 | (B) Identify discontinuity by the number of its neighbor(degree). |
| 407 | If the degree < 4(up/right/buttom/left). We will go through following steps: |
| 408 | (1) Add the discontinuity pixel "node" to graph "discont_graph". |
| 409 | (2) Find "node"'s cross neighbor(up/right/buttom/left) "ne_node". |
| 410 | - If the cross neighbor "ne_node" is a discontinuity pixel(degree("ne_node") < 4), |
| 411 | (a) add it to graph "discont_graph" and build the connection between "ne_node" and "node". |
| 412 | (b) label its cross neighbor as invalid pixels "inval_diag_candi" to avoid building |
| 413 | connection between original discontinuity pixel "node" and "inval_diag_candi". |
| 414 | - Otherwise, find "ne_node"'s cross neighbors, called diagonal candidate "diag_candi". |
| 415 | - The "diag_candi" is diagonal to the original discontinuity pixel "node". |
| 416 | - If "diag_candi" exists, go to step(3). |
| 417 | (3) A diagonal candidate "diag_candi" will be : |
| 418 | - added to the "discont_graph" if its degree < 4. |
| 419 | - connected to the original discontinuity pixel "node" if it satisfied either |
| 420 | one of following criterion: |
| 421 | (a) the difference of disparity between "diag_candi" and "node" is smaller than default threshold. |
| 422 | (b) the "diag_candi" and "node" face the same opposite pixel. (See. function "tear_edges") |
| 423 | (c) Both of "diag_candi" and "node" must_connect to each other. (See. function "combine_end_node") |
| 424 | (C) Aggregate each connected part in "discont_graph" into "discont_ccs" (A.K.A. depth edge). |
| 425 | ''' |
| 426 | for node in LDI.nodes: |
| 427 | if not(LDI.graph['bord_up'] + 1 <= node[0] <= LDI.graph['bord_down'] - 2 and \ |
| 428 | LDI.graph['bord_left'] + 1 <= node[1] <= LDI.graph['bord_right'] - 2): |
| 429 | continue |
| 430 | neighbors = [*LDI.neighbors(node)] |
| 431 | if len(neighbors) < 4: |
| 432 | add_new_node(discont_graph, node) |
| 433 | diag_candi_anc, inval_diag_candi, discont_nes = set(), set(), set() |
| 434 | for ne_node in neighbors: |
| 435 | if len([*LDI.neighbors(ne_node)]) < 4: |
| 436 | add_new_node(discont_graph, ne_node) |
| 437 | add_new_edge(discont_graph, ne_node, node) |
| 438 | discont_nes.add(ne_node) |
| 439 | else: |
| 440 | diag_candi_anc.add(ne_node) |
| 441 | inval_diag_candi = set([inval_diagonal for ne_node in discont_nes for inval_diagonal in LDI.neighbors(ne_node) if \ |
| 442 | abs(inval_diagonal[0] - node[0]) < 2 and abs(inval_diagonal[1] - node[1]) < 2]) |
no test coverage detected