-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.ml
208 lines (168 loc) · 5.3 KB
/
build.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
open OImages;;
open Images;;
open Rgb24;;
(*
#use "/usr/lib/ocaml/3.09.2/camlimages/images.mli";;
#use "/usr/lib/ocaml/3.09.2/camlimages/rgb24.mli";;
*)
exception Format;;
exception Color of (int * int * int);;
type links = bool * bool * bool * bool;;
type color = White | Black;;
type coords = int * int;;
class['a] region = object
val nodes:('a Queue.t) = Queue.create ()
val nbrs:(coords, 'a) Hashtbl.t
= Hashtbl.create 127
method nodes = nodes
method nbrs = nbrs
end;;
(* type node = WhiteN of (links * region * White) | BlackN of (links * Black);; *)
type node = WhiteN of (links * node region) | BlackN of (links);;
(* type neighbour = node * coords *)
(* let factor = 0.75 *)
(* let mk_region () =
{ nodes=Queue.create (), nbrs=Hashtbl.create 127 () };; *)
let pix = 2;;
let load_img () =
let file = "input.png" in
let fmt, _ = Images.file_format file in
print_endline (Images.extension fmt);
(* match OImages.load file [] with
| Rgb24 img -> img
| _ -> raise Format *)
let img = OImages.load file [] in
(file, fmt, OImages.rgb24 img)
;;
let merge_regions target source =
if target == source then ()
else begin
Queue.transfer source#nodes target#nodes;
(* Hashtbl.iter
(fun k v -> Hashtbl.add target#nbrs k v)
source#nbrs *)
end
;;
let adjust_region regions matrix (i, j) (k, l) =
let node = matrix.(i).(j)
and nbr = matrix.(k).(l)
in
match node, nbr with
| WhiteN (links, source), WhiteN (_, target) ->
Hashtbl.remove regions (Oo.id source);
Hashtbl.add regions (Oo.id target) target;
merge_regions target source;
matrix.(i).(j) <- WhiteN (links, target)
| BlackN (_), WhiteN (_, target) ->
(* Hashtbl.add target#nbrs (i, j) node *) ()
| WhiteN (_, target), BlackN (_) ->
(* Hashtbl.add target#nbrs (k, l) node; *)
Hashtbl.add regions (Oo.id target) target
| BlackN (_), BlackN (_) -> ()
;;
let adjust_links matrix i j =
let w = (if i=0 then false else true) in
let n = (if j=0 then false else true) in
let node = matrix.(i).(j) in
let node =
if w then
begin
let wnode = matrix.(i-1).(j) in
match (wnode, node) with
| WhiteN _, WhiteN _
| BlackN _, BlackN _ -> node
| BlackN (wn, _, ws, ww), WhiteN ((n, e, s, _), region)
| WhiteN ((wn, _, ws, ww), region), BlackN (n, e, s, _) ->
let wlinks = (wn, false, ws, ww) in
let links = (n, e, s, false) in
let (wnode, node) = match wnode with
| BlackN _ -> BlackN (wlinks), WhiteN (links, region)
| WhiteN _ -> WhiteN (wlinks, region), BlackN (links)
in matrix.(i-1).(j) <- wnode;
node
end
else node
in
let node =
if n then
begin
let nnode = matrix.(i).(j-1) in
match (nnode, node) with
| WhiteN _, WhiteN _
| BlackN _, BlackN _ -> node
| BlackN (nn, ne, _, nw), WhiteN ((_, e, s, w), region)
| WhiteN ((nn, ne, _, nw), region), BlackN (_, e, s, w) ->
let nlinks = (nn, ne, false, nw) in
let links = (false, e, s, w) in
let (nnode, node) = match nnode with
| BlackN _ -> BlackN (nlinks), WhiteN (links, region)
| WhiteN _ -> WhiteN (nlinks, region), BlackN (links)
in matrix.(i).(j-1) <- nnode;
node
end
else node
in matrix.(i).(j) <- node
;;
let build_regions (matrix: node array array) regions =
let () = match matrix.(0).(0) with
| WhiteN (_, first) ->
Hashtbl.add regions (Oo.id first) first
| _ -> ()
in
Array.iteri (fun i arr ->
Array.iteri (fun j _ ->
if j>0 then
adjust_region regions matrix (i, j) (i, j-1);
if i>0 then
adjust_region regions matrix (i, j) (i-1, j);
adjust_links matrix i j
) arr
) matrix
;;
(*let punch matrix =
()
;;*)
let build () : string * Images.format * node array array * int * int =
let (file, format, img) = load_img () in
let (w, h) = (img#width, img#height) in
let (w, h) = (w - (w mod pix), h - (h mod pix)) in
let mk_cell x y =
(* match x, y with
| (w/pix, _) | (h/pix, _) -> ()
| (_, _) -> *)
let xfrom = x*pix in
let xuntil = xfrom + pix in
let yfrom = y*pix in
let yuntil = yfrom + pix in
let rec color i j white black =
match i, j with
| (x, y) when y=yuntil -> (white, black)
| (x, y) when x=xuntil && y<yuntil -> color xfrom (j+1) white black
| (_, _) ->
let rgb = img#get i j in
match (rgb.r, rgb.g, rgb.b) with
| 0, 0, 0 -> color (i+1) j white (black+1)
| 255, 255, 255 -> color (i+1) j (white+1) black
| _, _, _ -> raise (Color (rgb.r, rgb.g, rgb.b))
in
let (wh, bl) = color xfrom yfrom 0 0 in
let links = (yfrom>0, xuntil<w, yuntil<h, xfrom>0) in
if (wh > bl)
then
let region = new region in
let node = WhiteN (links, region) in
Queue.push node region#nodes;
node
else BlackN (links)
in
(* let mk_subarr x = Array.init (h/pix) (mk_cell x) in *)
print_endline ("starting array: " ^ (string_of_int (w/pix)) ^ ", " ^ (string_of_int (h/pix)));
let matrix = Array.init (w/pix)
(fun x -> Array.init (h/pix) (mk_cell x))
in print_endline ("ready array");
let regions = Hashtbl.create 127 in
build_regions matrix regions;
print_endline "ready regions";
(*punch matrix;*)
(file, format, matrix, w/pix, h/pix)
;;