rogermt commited on
Commit
bb1e82c
·
verified ·
1 Parent(s): 014e988

Move own-solver/neurogolf_solver/solvers/edge.py to own-solver/

Browse files
own-solver/neurogolf_solver/solvers/edge.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Edge/boundary detection solver — Laplacian Conv.
3
+
4
+ v5.2: 0 matches in current task set (edge definition too strict).
5
+ Kept for future variants (per-color edges, interior-only edges, etc.).
6
+ """
7
+
8
+ import numpy as np
9
+ from onnx import helper, numpy_helper
10
+ from ..onnx_helpers import mk, _make_int64_init, _build_pad_node
11
+ from ..data_loader import get_exs, fixed_shapes
12
+ from ..constants import GH, GW
13
+
14
+
15
+ def _has_edges(inp, out, edge_color, bg_color=0):
16
+ """Check if output is edge detection of input."""
17
+ h, w = inp.shape
18
+ for r in range(h):
19
+ for c in range(w):
20
+ pix = inp[r, c]
21
+ is_edge = False
22
+ if pix != bg_color:
23
+ for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
24
+ nr, nc = r + dr, c + dc
25
+ if 0 <= nr < h and 0 <= nc < w:
26
+ if inp[nr, nc] != pix:
27
+ is_edge = True
28
+ break
29
+ else:
30
+ is_edge = True
31
+ break
32
+ expected = edge_color if is_edge else bg_color
33
+ if out[r, c] != expected:
34
+ return False
35
+ return True
36
+
37
+
38
+ def _build_edge_model(IH, IW, edge_color, bg_color=0):
39
+ """Build ONNX model for edge detection via Laplacian conv."""
40
+ pad_h, pad_w = GH - IH, GW - IW
41
+
42
+ ch_sel = np.zeros((1, 10, 1, 1), dtype=np.float32)
43
+ for c in range(10):
44
+ if c != bg_color:
45
+ ch_sel[0, c, 0, 0] = 1.0
46
+
47
+ lap_k = np.array([[0, -1, 0],
48
+ [-1, 4, -1],
49
+ [0, -1, 0]], dtype=np.float32).reshape(1, 1, 3, 3)
50
+
51
+ edge_oh = np.zeros((1, 10, 1, 1), dtype=np.float32)
52
+ edge_oh[0, edge_color, 0, 0] = 1.0
53
+ bg_oh = np.zeros((1, 10, 1, 1), dtype=np.float32)
54
+ bg_oh[0, bg_color, 0, 0] = 1.0
55
+
56
+ inits = [
57
+ _make_int64_init('sl_st', [0, 0, 0, 0]),
58
+ _make_int64_init('sl_en', [1, 10, IH, IW]),
59
+ numpy_helper.from_array(ch_sel, 'ch_sel'),
60
+ numpy_helper.from_array(lap_k, 'lap_k'),
61
+ numpy_helper.from_array(np.float32(0.5), 'thresh'),
62
+ numpy_helper.from_array(edge_oh, 'edge_oh'),
63
+ numpy_helper.from_array(bg_oh, 'bg_oh'),
64
+ ]
65
+
66
+ nodes = [
67
+ helper.make_node('Slice', ['input', 'sl_st', 'sl_en'], ['cropped']),
68
+ helper.make_node('Conv', ['cropped', 'ch_sel'], ['occ'], kernel_shape=[1, 1]),
69
+ helper.make_node('Conv', ['occ', 'lap_k'], ['lap_out'], kernel_shape=[3, 3], pads=[1, 1, 1, 1]),
70
+ helper.make_node('Abs', ['lap_out'], ['lap_abs']),
71
+ helper.make_node('Greater', ['lap_abs', 'thresh'], ['is_edge_raw']),
72
+ helper.make_node('Greater', ['occ', 'thresh'], ['is_occ']),
73
+ helper.make_node('And', ['is_edge_raw', 'is_occ'], ['is_edge']),
74
+ helper.make_node('Where', ['is_edge', 'edge_oh', 'bg_oh'], ['result_small']),
75
+ ]
76
+ nodes.append(_build_pad_node('result_small', 'output', pad_h, pad_w, inits))
77
+ return mk(nodes, inits)
78
+
79
+
80
+ def s_edge_detect(td):
81
+ """Edge detection solver: output = boundary pixels of input shapes."""
82
+ exs = get_exs(td)
83
+ sp = fixed_shapes(td)
84
+ if sp is None:
85
+ return None
86
+ (IH, IW), (OH, OW) = sp
87
+ if (IH, IW) != (OH, OW):
88
+ return None
89
+
90
+ for bg_color in [0]:
91
+ out_colors = set()
92
+ for _, out in exs:
93
+ out_colors.update(out.flatten())
94
+ for edge_color in out_colors:
95
+ if edge_color == bg_color:
96
+ continue
97
+ if all(_has_edges(inp, out, edge_color, bg_color) for inp, out in exs):
98
+ return _build_edge_model(IH, IW, edge_color, bg_color)
99
+ return None