get("#121") -- compareTables
get("#348") -- bright and rgb
maxSize = {width=100, height=50}
minSize = {width=4, height=4}
threshold = 0.5
wandSize = 2 -- magic wand size
function cloneRectangle(r)
return newRectangle(r.x, r.y, r.width, r.height)
end
function newRectangle(x, y, w, h)
return {x=x, y=y, width=w, height=h}
end
-- returns rectangle
function magicWand(image, x, y)
local r = newRectangle(x, y, 1, 1)
while true do
local last = cloneRectangle(r)
expandLeft(image, r)
if tooLarge(r) then return nil end
expandTop(image, r)
if tooLarge(r) then return nil end
expandRight(image, r)
if tooLarge(r) then return nil end
expandBottom(image, r)
if tooLarge(r) then return nil end
if compareTables(last, r) then
if r.width >= minSize.width and r.height >= minSize.width then
return r
else
return nil
end
end
end
end
function tooLarge(r)
return maxSize ~= nil and (r.width > maxSize.width or r.height > maxSize.height)
end
function expandLeft(image, r)
local newX = math.max(r.x - wandSize, 0)
if newX == r.x then return end
newX = searchFromLeft(image, newRectangle(newX, r.y, r.x-newX, r.height))
r.width = r.width+r.x-newX
r.x = newX
end
function searchFromLeft(image, r)
for x = r.x, r.x+r.width-1 do
if regionNotEmpty(image, newRectangle(x, r.y, 1, r.height)) then
return x
end
end
return r.x+r.width
end
function expandRight(image, r)
local newX = math.min(r.x + r.width + wandSize, image.width)
if newX == r.x+r.width then return end
newX = searchFromRight(image, newRectangle(r.x+r.width, r.y, newX-(r.x+r.width), r.height))
r.width = newX-r.x
end
function searchFromRight(image, r)
for x = r.x+r.width-1, r.x, -1 do
if regionNotEmpty(image, newRectangle(x, r.y, 1, r.height)) then
return x+1
end
end
return r.x
end
function expandTop(image, r)
local newY = math.max(r.y - wandSize, 0)
if newY == r.y then return end
newY = searchFromTop(image, newRectangle(r.x, newY, r.width, r.y-newY))
r.height = r.height+r.y-newY
r.y = newY
end
function searchFromTop(image, r)
for y = r.y, r.y+r.height-1 do
if regionNotEmpty(image, newRectangle(r.x, y, r.width, 1)) then
return y
end
end
return r.y+r.height
end
function expandBottom(image, r)
local newY = math.min(r.y + r.height + wandSize, image.height)
if newY == r.y+r.height then return end
newY = searchFromBottom(image, newRectangle(r.x, r.y + r.height, r.width, newY-(r.y+r.height)))
r.height = newY-r.y
end
function searchFromBottom(image, r)
for y = r.y+r.height-1, r.y, -1 do
if regionNotEmpty(image, newRectangle(r.x, y, r.width, 1)) then
return y+1
end
end
return r.y
end
-- we're looking for dark pixels this time
function regionNotEmpty(image, r)
--return image.clip(rectangle).anyPixelBrighterThan(threshold)
for y=r.y, r.y+r.height-1 do
for x=r.x, r.x+r.width-1 do
if bright(rgb(image.getInt(x, y))) < threshold then
return true
end
end
end
return false
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: | 1121 / 231 |
| Referenced in: | [show references] |