PDA

View Full Version : Image to Shape


MerlinEl
05-25-2011, 06:27 PM
Hi

Im' try to trace white areas on image and convert outline to shape.

steps
desaturation -- done
treshold --done
trace shape
-- crashing when I try put a vertex for every white pixel (for test)
-- I need some help here :-)


try DestroyDialog unnamedRollout catch ()
rollout unnamedRollout "Image to Shape v0.01" width:372 height:392 --default size
(
local grab_img, desatured_img, tresholded_img
bitmap bmp1 "Bitmap" pos:[4,76] width:364 height:312
spinner spn_treeshold "" pos:[192,36] width:84 height:16 range:[1,255,120] type:#integer scale:1
progressBar progbar "ProgressBar" pos:[4,60] width:364 height:12 color:green

button btn_capture_image "Capture" pos:[4,4] width:88 height:24
button btn_paste "Paste" pos:[4,32] width:88 height:24
button btn_desature "Desature" pos:[96,4] width:88 height:24
button btn_treeshold "Treeshold" pos:[96,32] width:88 height:24
button btn_trace "Shape Trace" pos:[188,4] width:88 height:24
button btn5 "4" pos:[280,4] width:88 height:24
button btn12 "5" pos:[280,32] width:88 height:24
fn getImage type =
(
local img = case type of
(
#capture: gw.getViewportDib()
#paste: getclipboardBitmap()
)
if img == undefined do return false
local w = img.width
local h = img.height
unnamedRollout.width = w
unnamedRollout.height = h
bmp1.width = w
bmp1.height = h
--local new_img = bitmap w h
--copy img new_img
bmp1.bitmap = img --new_img
progbar.value = 0
grab_img = img
)
fn desatureImage img =
(
local w = img.width
local h = img.height
local new_img = bitmap w h

for i = 0 to (h-1) do
(
local new_line = #()
local p = getpixels img [0,i] w --a horizontal pixel ilne

for j = 1 to w do
(
p[j].s = 0
new_line[j] = p[j]

)
setpixels new_img [0,i] new_line
progbar.value = 100.*i/h
)
bmp1.bitmap = new_img
desatured_img = new_img
)
fn treesholdImage img =
(
local w = img.width
local h = img.height
local new_img = bitmap w h

for i = 0 to (h-1) do
(
local new_line = #()
local p = getpixels img [0,i] w --a horizontal pixel ilne

for j = 1 to w do
(
if p[j].v > spn_treeshold.value then p[j].v = 255 else p[j].v = 0
new_line[j] = p[j]

)
setpixels new_img [0,i] new_line
progbar.value = 100.*i/h
)
bmp1.bitmap = new_img
tresholded_img = new_img
)
fn shapeTrace img =
(
local mem = heapSize -- in my pc is default 12m
if (mem as integer)/1000000 < 50 do heapSize = 50*1000000 -- up to 50m
local w = img.width
local h = img.height
local verts = #()
max create mode
for i = 0 to (h-1) do with redraw off
(
local p = getpixels img [0,i] w --a horizontal pixel ilne
for j = 1 to w do
(
--find first white pixel from left up corner
if p[j] == white do --white pixel found
(
--test
verts +=#([j,i,0])
)
progbar.value = 100.*i/h
)
local me = mesh vertices:verts faces:#()
update me
select me
CompleteRedraw()
)
heapSize = mem
)
on btn_capture_image pressed do (getImage #capture)
on btn_paste pressed do (getImage #paste)
on btn_desature pressed do (desatureImage grab_img)
on btn_treeshold pressed do (treesholdImage desatured_img)
on btn_trace pressed do (shapeTrace tresholded_img )
on spn_treeshold changed val do ()
)
CreateDialog unnamedRollout

MerlinEl
05-26-2011, 09:49 AM
the crash is caused because the array size it was to big :rolleyes:
now Iím create vertices during process without array.

the test is ok :-)

next step is trace outline for every white area.
any ideas are welcome :D

how to use this test:
1 use Capture or Paste to get an image
2 press Desaturate and after Threshold
3 press button Shape Trace

after finishing look from top view to see the vertices.


try DestroyDialog unnamedRollout catch ()
rollout unnamedRollout "Image to Shape v0.01" width:372 height:392 --default size
(
local grab_img, desatuated_img, tresholded_img
bitmap bmp1 "Bitmap" pos:[4,76] width:364 height:312
spinner spn_threshold "" pos:[192,36] width:84 height:16 range:[1,255,120] type:#integer scale:1
progressBar progbar "ProgressBar" pos:[4,60] width:364 height:12 color:green

button btn_capture_image "Capture" pos:[4,4] width:88 height:24
button btn_paste "Paste" pos:[4,32] width:88 height:24
button btn_desatuate "Desaturate" pos:[96,4] width:88 height:24
button btn_threshold "Threshold" pos:[96,32] width:88 height:24
button btn_trace "Shape Trace" pos:[188,4] width:88 height:24
button btn5 "4" pos:[280,4] width:88 height:24
button btn12 "5" pos:[280,32] width:88 height:24
fn createEPoly name pos:[0,0,0] =
(
local obj = mesh vertices:#() faces:#() name:(uniqueName name)
convertToPoly obj ; redrawViews() ; select obj ; return obj
)
fn createVertex obj pos =( polyOp.createVert obj pos )
fn getImage type =
(
local img = case type of
(
#capture: gw.getViewportDib()
#paste: getclipboardBitmap()
)
if img == undefined do return false
local w = img.width
local h = img.height
unnamedRollout.width = w
unnamedRollout.height = h
bmp1.width = w
bmp1.height = h
--local new_img = bitmap w h
--copy img new_img
bmp1.bitmap = img --new_img
progbar.value = 0
grab_img = img
)
fn desatuateImage img =
(
local w = img.width
local h = img.height
local new_img = bitmap w h

for i = 0 to (h-1) do
(
local new_line = #()
local p = getpixels img [0,i] w --a horizontal pixel ilne

for j = 1 to w do
(
p[j].s = 0
new_line[j] = p[j]

)
setpixels new_img [0,i] new_line
progbar.value = 100.*i/h
)
bmp1.bitmap = new_img
desatuated_img = new_img
)
fn thresholdImage img =
(
local w = img.width
local h = img.height
local new_img = bitmap w h

for i = 0 to (h-1) do
(
local new_line = #()
local p = getpixels img [0,i] w --a horizontal pixel ilne

for j = 1 to w do
(
if p[j].v > spn_threshold.value then p[j].v = 255 else p[j].v = 0
new_line[j] = p[j]

)
setpixels new_img [0,i] new_line
progbar.value = 100.*i/h
)
bmp1.bitmap = new_img
tresholded_img = new_img
)
fn shapeTrace img =
(
if (heapSize as integer)/1000000 < 50 do heapSize = 50*1000000 -- if heap size is less than 50m then incerase
local w = img.width
local h = img.height
local verts = #()
max create mode
local obj = createEPoly "trace test"
for i = 0 to (h-1) do with redraw off
(
local p = getpixels img [0,i] w --a horizontal pixel ilne
for j = 1 to w do
(
--find first white pixel from left up corner
if p[j] == white do --white pixel found
(
--test
createVertex obj [j,i,0]
)
progbar.value = 100.*i/h
)
CompleteRedraw()
)
)
on btn_capture_image pressed do (getImage #capture)
on btn_paste pressed do (getImage #paste)
on btn_desatuate pressed do (desatuateImage grab_img)
on btn_threshold pressed do (thresholdImage desatuated_img)
on btn_trace pressed do (shapeTrace tresholded_img )
on spn_threshold changed val do ()
)
CreateDialog unnamedRollout

VVaari
06-09-2011, 08:07 AM
This is really interesting stuff MerlinEl! I just started researching if i could trace bitmap (to a spline maybe) and fracture objects with it, like in RayFire. I gotta test your code tonight and play with it :)

MerlinEl
06-09-2011, 09:46 AM
This is really interesting stuff MerlinEl! I just started researching if i could trace bitmap (to a spline maybe) and fracture objects with it, like in RayFire. I gotta test your code tonight and play with it :)

Hi

Yes Yes VVaari, is quite interesting :-D I like to play with some riddles like this ;-)

Here is my tip for collecting pixels ...

http://img121.imageshack.us/img121/7973/tracealgorithm.jpg
should be work :-)

jonadb
06-09-2011, 10:18 AM
How about starting with a dense plane, iirc volume select (or another modifier, not behind a workstation at the monent) can use a grayscale map to select verts, delete unselected. Then use optimize an get of the inner mesh structure.

MerlinEl
06-09-2011, 11:54 AM
How about starting with a dense plane, iirc volume select (or another modifier, not behind a workstation at the monent) can use a grayscale map to select verts, delete unselected. Then use optimize an get of the inner mesh structure.

Hi jonadb

Im not realy sure if I understand you...
1)
filling white area with vertices
2)
bulid a mesh
3)
select outline?

is not bad , but if you have more complex picture with many shapes?

jonadb
06-09-2011, 12:13 PM
Not sure which modifier, but there is on which can select subobjects by texture intensity.

so you start with a plane with for example 500x500 segments, Add the modifier with your pre-procesed bitmap. It will select all faces or verts that have a texture value above 127. Delete the unselected and presto!

I've used thus once to turn a bitmap worldmap into a mesh, worked great!

Their will be alot of redundant verts in the middle of areas, you can optimize those out.

If you want a spline, extrude the mesh and get the spline intersection with a plane.

PiXeL_MoNKeY
06-09-2011, 07:02 PM
Not sure which modifier, but there is on which can select subobjects by texture intensity.Volume Select.

-Eric

denisT
06-09-2011, 07:51 PM
If you want a spline, extrude the mesh and get the spline intersection with a plane.

select open edges (borders) and create shape from selected edges.

denisT
06-09-2011, 07:52 PM
Volume Select.

-Eric

absolutely right. that's the easiest way.

MerlinEl
06-10-2011, 08:22 AM
Hi

Thanks for you tip guys :-) :thumbsup:

Volume Select is very interesting modifier. I will examine it a bit ;-)
also i found a nice video on you-tube
http://youtu.be/MYfQukbSbyg

CGTalk Moderation
06-10-2011, 08:22 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.