Notifications
Clear all

[Closed] Image to Shape

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


10 Replies

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

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


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 I like to play with some riddles like this

Here is my tip for collecting pixels …

should be work

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.

1 Reply
(@merlinel)
Joined: 11 months ago

Posts: 0

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?

Not sure which modifier, but there is on which can select subobjects by texture intensity.

so you start with a plane with for example 500×500 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.

3 Replies
(@pixel_monkey)
Joined: 11 months ago

Posts: 0

Volume Select.

-Eric

(@denist)
Joined: 11 months ago

Posts: 0

absolutely right. that’s the easiest way.

(@denist)
Joined: 11 months ago

Posts: 0

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

Hi

Thanks for you tip guys

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