1 | get("#121") -- compareTables |
2 | get("#348") -- bright and rgb |
3 | |
4 | maxSize = {width=100, height=50} |
5 | minSize = {width=4, height=4} |
6 | threshold = 0.5 |
7 | wandSize = 2 -- magic wand size |
8 | |
9 | function cloneRectangle(r) |
10 | return newRectangle(r.x, r.y, r.width, r.height) |
11 | end |
12 | |
13 | function newRectangle(x, y, w, h) |
14 | return {x=x, y=y, width=w, height=h} |
15 | end |
16 | |
17 | -- returns rectangle |
18 | function magicWand(image, x, y) |
19 | local r = newRectangle(x, y, 1, 1) |
20 | |
21 | while true do |
22 | local last = cloneRectangle(r) |
23 | expandLeft(image, r) |
24 | if tooLarge(r) then return nil end |
25 | expandTop(image, r) |
26 | if tooLarge(r) then return nil end |
27 | expandRight(image, r) |
28 | if tooLarge(r) then return nil end |
29 | expandBottom(image, r) |
30 | if tooLarge(r) then return nil end |
31 | if compareTables(last, r) then |
32 | if r.width >= minSize.width and r.height >= minSize.width then |
33 | return r |
34 | else |
35 | return nil |
36 | end |
37 | end |
38 | end |
39 | end |
40 | |
41 | function tooLarge(r) |
42 | return maxSize ~= nil and (r.width > maxSize.width or r.height > maxSize.height) |
43 | end |
44 | |
45 | function expandLeft(image, r) |
46 | local newX = math.max(r.x - wandSize, 0) |
47 | if newX == r.x then return end |
48 | newX = searchFromLeft(image, newRectangle(newX, r.y, r.x-newX, r.height)) |
49 | r.width = r.width+r.x-newX |
50 | r.x = newX |
51 | end |
52 | |
53 | function searchFromLeft(image, r) |
54 | for x = r.x, r.x+r.width-1 do |
55 | if regionNotEmpty(image, newRectangle(x, r.y, 1, r.height)) then |
56 | return x |
57 | end |
58 | end |
59 | return r.x+r.width |
60 | end |
61 | |
62 | function expandRight(image, r) |
63 | local newX = math.min(r.x + r.width + wandSize, image.width) |
64 | if newX == r.x+r.width then return end |
65 | newX = searchFromRight(image, newRectangle(r.x+r.width, r.y, newX-(r.x+r.width), r.height)) |
66 | r.width = newX-r.x |
67 | end |
68 | |
69 | function searchFromRight(image, r) |
70 | for x = r.x+r.width-1, r.x, -1 do |
71 | if regionNotEmpty(image, newRectangle(x, r.y, 1, r.height)) then |
72 | return x+1 |
73 | end |
74 | end |
75 | return r.x |
76 | end |
77 | |
78 | function expandTop(image, r) |
79 | local newY = math.max(r.y - wandSize, 0) |
80 | if newY == r.y then return end |
81 | newY = searchFromTop(image, newRectangle(r.x, newY, r.width, r.y-newY)) |
82 | r.height = r.height+r.y-newY |
83 | r.y = newY |
84 | end |
85 | |
86 | function searchFromTop(image, r) |
87 | for y = r.y, r.y+r.height-1 do |
88 | if regionNotEmpty(image, newRectangle(r.x, y, r.width, 1)) then |
89 | return y |
90 | end |
91 | end |
92 | return r.y+r.height |
93 | end |
94 | |
95 | function expandBottom(image, r) |
96 | local newY = math.min(r.y + r.height + wandSize, image.height) |
97 | if newY == r.y+r.height then return end |
98 | newY = searchFromBottom(image, newRectangle(r.x, r.y + r.height, r.width, newY-(r.y+r.height))) |
99 | r.height = newY-r.y |
100 | end |
101 | |
102 | function searchFromBottom(image, r) |
103 | for y = r.y+r.height-1, r.y, -1 do |
104 | if regionNotEmpty(image, newRectangle(r.x, y, r.width, 1)) then |
105 | return y+1 |
106 | end |
107 | end |
108 | return r.y |
109 | end |
110 | |
111 | -- we're looking for dark pixels this time |
112 | function regionNotEmpty(image, r) |
113 | --return image.clip(rectangle).anyPixelBrighterThan(threshold) |
114 | for y=r.y, r.y+r.height-1 do |
115 | for x=r.x, r.x+r.width-1 do |
116 | if bright(rgb(image.getInt(x, y))) < threshold then |
117 | return true |
118 | end |
119 | end |
120 | end |
121 | return false |
122 | end |
test run test run with input download show line numbers
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #363 |
Snippet name: | Magic Wand Algorithm |
Eternal ID of this version: | #363/1 |
Text MD5: | b3ebdd59c5a81fcd284ee7c02cb80622 |
Author: | stefan |
Category: | image recognition |
Type: | Lua code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-01-31 00:14:53 |
Source code size: | 3207 bytes / 122 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 886 / 178 |
Referenced in: | [show references] |