Background Image Script?
 1-20  21-32

Next
 From:  FDP
6162.1 
Would it be possible to script the background image so that it can flip through an animation stack? My specific use is tracing data from a CT scan (where each Z layer of the scan is a separate frame in an animation).

Perhaps something could be rigged that allows for incremented frame numbers as the last 5 characters/digits of a filename (e.g. frame00001, frame00002, etc), linked to the image reload function?

For my use a further super-helpful feature would be if all existing curves on screen could be automatically grouped into a named object with a name that matched the open BG frame ( e.g. frame00001) every time the BG frame/image was incremented. Perhaps this could be done by selecting all "UNNAMED" objects and then naming them the existing frame number before reloading?

Regards,
FDP
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.2 In reply to 6162.1 
Hi FDP, I think it should be possible to script those things but before I attempt to do it, it would probably help a lot if you could post an example file that was set up with some example background images and curves how you would expect to have them before triggering the script.

That would help to make sure that I'm totally on the same page as you with what the script needs to do.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.3 In reply to 6162.2 
Thanks Michael!

I've attached a quick example. In this example the image sequence is not starting at 00000, but it is otherwise pretty simple (no missing frames or spaces in the filenames).

For each frame I've created an object with the same name. I've embedded the images in this example just to make sure you can see what is going on (embedding would not be normal or desired, I turned it on only to make sure you could see the images in the example).

I've gone ahead and created a simple piece of (somewhat inaccurate) geometry to show what the end output might look like (for example, there is equal spacing between the curves from each frame). I would expect the that the user would create the z-spacing manually (unless it is easy to change the z-position of the Unnamed geometry automatically based on a user specified value in between each image load, which would of course be a helpful option). From a user operations standpoint the user is essentially extruding out a model from the image sequence layer by layer.

I can go through and do this example step by step in separate files if this would be more helpful to illustrate the process, just let me know!

I'm always amazed at how quickly you respond to support requests. Thanks again!

All the best,
FDP

UPDATE: Also, I realized that in the example I have separate background images for each frame. I just did this to get them all in there to show the process. I don't think this would be desirable in the implementation, as you could ultimately have hundreds of frames (which would lead to a painful amount of background images).
Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.4 In reply to 6162.3 
Hi FDP, sorry I didn't get a chance to take a look at your example until now.

I'm confused by one part that you wrote though:
quote:

UPDATE: Also, I realized that in the example I have separate background images for each frame. I just did this to get them all in there to show the process. I don't think this would be desirable in the implementation, as you could ultimately have hundreds of frames (which would lead to a painful amount of background images).


I had originally thought that you were talking about having a bunch of separate background images and that you just wanted to switch the visibility of them with a script, hiding the current one and showing the next one in the sequence.

But here now you're talking about not wanting to have individual background images, so it seems that what I was thinking you were asking about just switching the "hidden" property of various background images is not really what you want.

Do you actually want just a single background image that switches to load a different image file from disk every time you trigger the script?

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
6162.5 
I see that there is an option to "Embed image data in 3dm file," so the images do not
need to be in the final 3dm file?

So memory is only utilized for the images when the images are added to the MoI screen?

If there are thousand of CAT scans, maybe they could be done in batches?

- Brian
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.6 In reply to 6162.5 
Hi Brian,

> I see that there is an option to "Embed image data in 3dm file," so the images do not
> need to be in the final 3dm file?

Yeah it's optional for whether the 3DM file will contain the actual image bits embedded inside of it or not, by default when you create a background image it will only reference a file on your disk. If you turn on that embed option for an image it will include the image bits inside the 3DM file which can be convenient for sending the file to other people since everything is contained in just one file.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.7 In reply to 6162.6 
Hi Michael & Brian,
Sorry for the delay in my response. I was originally thinking that there would be a single background image, and the script would merely control what file it actually pointed to.

The method Michael proposed of having it load a new image into a new background (with identical coordinates) and then hiding the previous version would probably work as well, but I could see having to manage hundreds of images getting a bit unpleasant from a user perspective, for example if the user wanted to hide the background, they might be forced to scroll through a list of hundreds of images.

What might be nice would be the ability to move in either direction with the background image, or even specify a frame number.

this is what I was thinking, in horribly written very general psuedocode:

background_file = userinput
background_filename = (background_file[0 to -5 characters])
background_frame = integer(background_file[-5 characters])
background_ext = extension
Z_increment = float(userinput)
Z_current = 0.0 (optionally let user set this)

increment function:
if userinput_frame_increment_command{
select curves with name("Unnammed")
selected curves new name = background_filename + background_frame
Z_current = Background_frame * Z_increment
selected curves.move(z) = Z_current
background_frame++
background_file = background_filename + background_frame + background_ext
reload background (error condition if no file found: optionally increment up to 5 times to search for missing frames, give user the option to search forward a given number of frames or end script)
}

decrement function:
if userinput_frame_decrement_command{
select curves with name("Unnammed")
selected curves new name = background_filename + background_frame
Z_current = background_frame * Z_increment
selected curves.move(z) = Z_current
background_frame--
background_file = background_filename + background_frame + background_ext
reload background (error condition if no file found: optionally increment up to 5 times to search for missing frames, give user the option to search forward a given number of frames or end script)
}

frame select function:
if userinput_frame_select_command{
frameseek= userinput_frame_number
select curves with name("Unnammed")
selected curves new name = background_filename + background_frame
Z_current = Background_frame * Z_increment
selected curves.move(z) = Z_current
background_frame = frameseek
background_file = background_filename + background_frame + background_ext
reload background (error condition if no file found: ask user to re-input or to cancel script)
}


Thanks,
FDP

Edit: Sorry, I am in kind of a rush and realized there were some errors. I've fixed it up a little, but I'm sure it is still a bit broken. Hope it helps to communicate my thoughts!

EDITED: 10 Sep 2013 by FDP

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
6162.8 
Some initial thoughts:

For the CAT scan analogy:

Making a distinction between the background image slice, and the layer on which
the 2D object is created.

Each image is a sequential slice, of the 3D object,
separated by an increment of ____ mm, which determines the layer of the traced
2d object. (The example is using the front frame, x,z.)

Each image slice is loaded with the same x,z (or x,y?) position and (non)rotation.
The image is "below" created objects? (or with objects or above objects?)
The transparency setting is ___?

A slice is loaded, and the user traces a 2D object on the new layer.
The previous 2D objects, (layers), need to be hidden?

The user can flip back and forth between 2d object layers, or background slices,
to glean 3D help for the 2D trace.

...
- Brian

EDITED: 10 Sep 2013 by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
6162.9 
Did a search for "Multiplanar Reconstruction."

JIM costs about 10X to 20X the cost of MoI.
http://www.xinapse.com/Manual/index.html

It has a nice NON clinical use disclaimer.
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.10 In reply to 6162.8 
Thanks Brian! I'm on my phone so replied inline.

Each image is a sequential slice, of the 3D object,
separated by an increment of ____ mm, which determines the layer of the traced
2d object. (The example is using the front frame, x,z.)
-Yes (although front frame might be X, Y depending on coordinate system used)

Each image slice is loaded with the same x,z (or x,y?) position and (non)rotation.
-Yes

The image is "below" created objects? (or with objects or above objects?)
-Yes, image should be below.

The transparency setting is ___?
-Standard user controllable would be best


A slice is loaded, and the user traces a 2D object on the new layer.
-Yes

The previous 2D objects, (layers), need to be hidden?
-This should be an option. Sometimes this is not desirable, sometimes it is (also in a perfect world sometimes the previous layer geometry would be copied and left on the new layer, but this should be optional)

The user can flip back and forth between 2d object layers, or background slices,
to glean 3D help for the 2D trace.
-Yes, although layers are easy enough to handle, but perhaps layer visibility could be optionally linked to BG frame selected?

...
- Brian
EDITED: 10 Sep 12:17 by BEMFARMER

 
 
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.11 In reply to 6162.9 
I haven't used Jim, I have used OsiriX to do some 3D reconstruction in the past It is a fantastic free and open-source Dicom viewer, but a terribly blunt tool for this kind of reconstruction.

The nice thing about MoI being a front-end to reconstruction is having the full power of a fast, efficient modeller instead of a basic 2D spline interface. The trick is keeping the units, etc, but that seems trivial!

It also occurred to me that the same general concept could be used to import, view and edit slices of gcode generated for 3d printing, although tools already exist for that... it might be useful to overlay gcode with original models.I should stop before I draw us off-topic :)

-FDP
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.12 In reply to 6162.7 
Hi FDP, that's really a quite complex script (or is it multiple different scripts) that you're talking about there, every sequence like "ask the user to do this or that" actually take a fair amount of time to write.

I can help you get started on it, you may need to build up the more complex parts of the script yourself.

Let's try building it up in some stages, how about an initial stage where it just increments an existing file and make sure that part is working ok for you first before trying to move on to more functionality.

I'll see if I can write some initial starting point for you to test with.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.13 In reply to 6162.11 
Hi FDP, I've attached an initial starting point - copy the attached IncrementImage.js file into the \commands folder inside of MoI's main installation folder. That will then make a new command named IncrementImage available. To trigger the command set up a keyboard shortcut for the command part of the shortcut key put in: IncrementImage (just plain IncrementImage, no "script:" prefix and no .js extension).

The command expects for there to be one already existing background image in the file. It will get the filename of that background image and split the name into pieces, increment the numeric piece and then set the new filename onto the image. Internally that causes a reload of the image and the image should update.

Note that currently it is assumed that the filenames have 5 numeric digits in them before the file extension part, and it's also assumed that all the images of the set have the same aspect ratio. The 3D-space image size stays the same during this reload and if the new images does not have the same pixel dimensions as the old one it will still be stretched to fit in the same area as the old one anyway.

One other note - when you're working on editing this command there is a setting that you should change first in moi.ini to prevent command files from being cached. Go to Options > General and push the "Edit .ini file" button. Then in the [UI] section of the .ini file set:
DisableFileCaching=y

By default MoI internally caches any command file that it reads off disk, which is annoying when you're making changes to them since it means you have to exit MoI and restart it to get the new script to be loaded. But if you set DisableFileCaching=y you can keep MoI open and it will reload the command file each time the command is launched instead.

- Michael

EDITED: 10 Sep 2013 by MICHAEL GIBSON

Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  bemfarmer
6162.14 In reply to 6162.13 
Tried the script with the chest samples, and also with the following brain scans, relabeled 00001, 00002, etc.
http://en.wikipedia.org/wiki/File:Computed_tomography_of_human_brain_-_large.png

The script works!
When the script gets to the end, the highest number, it seems to keep reloading the last image, with label number incremented
higher each time.

- Brian

When I misspelled Brain00006 as Brian00006, it reloaded Brain00005 as 00006, and on the next load, loaded 00007. :-) (OK)

EDITED: 10 Sep 2013 by BEMFARMER

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.15 In reply to 6162.14 
Hi Brian,

> When the script gets to the end, the highest number, it seems to keep reloading
> the last image, with label number incremented
> higher each time.

Yeah when you get to a file that does not exist, the reload fails and the last valid image still stays as the one displayed.

Right now there's not a very convenient way for a script to detect if a file exists or not, so for now you would just want to pay attention to not go past the last one, or modify the script to have the last number set in the script so that it can look at that to know if it's at the end one or not.

I'll add in a method to the script layer for the next v3 beta to make it easier for a script to know if a given file exists or not.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.16 In reply to 6162.15 
Thanks Michael!
I'll give this a try tonight! Can't thank you enough!

-FDP
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.17 In reply to 6162.16 
For coding, I'm sorry to ask this basic question (didn't find anything with Googling the site), is there a js console available in MoI?

Thanks,
FDP
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.18 In reply to 6162.17 
Hi FDP,

> For coding, I'm sorry to ask this basic question (didn't find anything with Googling the site),
> is there a js console available in MoI?

Sorry, no there isn't anything as sophisticated as that available yet, you just have to edit the file in a separate text editor.

I'd like to make a much more sophisticated scripting environment in the future but it will be quite a while before I'm able to do that, there is a lot of work involved.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  FDP
6162.19 In reply to 6162.18 
Thanks Michael!
I got the script to work! Making a decrement version was super easy (just changed line 63 to "--num;").

Now I just have to figure out how to take a modifier for the command (e.g. fork at --num or ++num).

Is there a way to select objects by name and then change that name? E.g. objectpicker(object.objectname == "Unnamed")?

-FDP
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
6162.20 In reply to 6162.19 
Hi FDP,

> Is there a way to select objects by name and then change that name?
> E.g. objectpicker(object.objectname == "Unnamed")?

You can get an object list of all current objects by doing moi.geometryDatabase.getObjects(); then if you want to only target "unnamed" objects look for objects that have a .name property that returns an empty string which is represented in JavaScript by just 2 quotes with nothing inside of them.

Here's an example:

code:
function SetObjectNames( newname )
{
	// Set any unnamed objects to have the given name.

	var objects = moi.geometryDatabase.getObjects();
	
	for ( var i = 0; i < objects.length; ++i )
	{
		var obj = objects.item(i);
		
		// An "unnamed" object will have an empty string as its name property.
		if ( obj.name == '' )
			obj.name = newname;	
	}
}


So a call to this function like: SetObjectNames( 'flimflam' ); will set any unnamed objects to have the name 'flimflam', but would not change objects that already have a name.

- Michael
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All

 

 
Show messages:  1-20  21-32