making a video using an array of images

Dear all,

I am very new at Igor and I am going to use it in my PhD research. My supervisor asked for me to create an algorithm that will use image files (ie jpg) in order to create a movie. I tried the bellow, but apparently is not correct. Could anyone suggest anything? Thank you.

Function A()

Newpath/O IgorSpace, "C:\Users\Public\Documents\Wavemetrics\IgorSpace" //Here I have my satellite images

print indexedDir(IgorSpace,0,0)

print indexedfile(IgorSpace, -1, ".jpg")

imageload /P=IgorSpace /T=jpg "1235.jpg" //I don't know if this command is useful

LoadPICT /P=IgorSpace "1235.jpg" sat1 //I understood that I have to load the image into a wave, for example 'sat1' here
newmovie /F=1 /O /P=IgorSpace /PICT=sat1 //finally I write this command to use the previous loaded image

closemovie

end
The approach you need involves a slightly different order:

0. Load the first image using ImageLoad and display in a graph window using NewImage/S=0. This will give you a full frame display of the image with no axes.
1. NewMovie -- you need to create a new movie at the start of the process and associate it with the image window.
2. Loop through the images:
2.1 Load each image using ImageLoad and overwrite the wave that is currently displayed.
2.2 add the frame to the movie using AddMovieFrame
3. Close the movie.

In step 2 you should probably use IndexedFile() and not IndexedDIR(). Note also that the resulting order may be different from what you expect so if the order of frames is important you have to make sure that you are loading the files in the required order.

You may want to examine a code example in File Menu->Example Experiments->Movies & Audio->FM Modulation Movie.

I hope this helps,

A.G.
WaveMetrics, Inc.
Thank you for the answer. I think that this will help me to understand the procedure in general.

I tried tis one:

imageload /O/P=IgorSpace /T=jpg /S=0
newimage /N=SatSet /S=0

but newimage command requires a wave reference.

I cannot understand where the image is loaded (is there any wave or sth like that?) and which is the name that I should use as a reference to the newimage command?
steeve88 wrote:
Thank you for the answer. I think that this will help me to understand the procedure in general.

I tried tis one:

imageload /O/P=IgorSpace /T=jpg /S=0
newimage /N=SatSet /S=0

but newimage command requires a wave reference.

I cannot understand where the image is loaded (is there any wave or sth like that?) and which is the name that I should use as a reference to the newimage command?


The nature of your comments suggest that you might benefit from going through the Getting Started Tutorial (if you have not done so already).

You do not need /S in Imageload because you seem to load jpeg files and so multiple/stacked images are not supported.

After you execute ImageLoad you can execute:
Print S_waveNames

or simply look in the Data Browser window to find out what waves where created. If you are not familiar with the Data Browser window it may be a good idea to get acquainted with it now. You will find it under Data Menu->Data Browser. You can also execute on the command line:
DisplayHelpTopic "Data Browser"


Note that ImageLoad tends to create waves based on the name of the image file. For example, if you load image.jpg then chances are that your wave name will be "image.jpg". A wave name containing a '.' is considered a liberal name and as such requires that you pass it to subsequent commands using single quotes as in 'image.jpg'. My personal preference is to rename the wave as soon as possible so I do not have to type silly quotes. In function code I use:
Wave w=$StringFromList(0,s_waveNames)  // wave reference to whatever the name of the wave may be.
Duplicate/O w,firstImageWave    // so only one NewImage needs to be executed outside the loop.
DoUpdate         // give it a chance to redraw the image.
AddMovieFrame        // add the latest frame to the movie.

Here I returned to my earlier suggestion that you start by loading and displaying a first image. Set the name of that wave to "firstImageWave" and in your loop overwrite that wave with the new images.

A.G.
Thank you for your really useful instructions. I followed them and I think that I am very close to the solution. The only problem that I have now is using the newmovie command.

I use the command below, but when I run my function, a message says that a picture name expected. The name of the picture is 1235.jpg and it also exists in data browser. What should be wrong here?

newmovie /F=1/P=IgorSpace/PICT='1235.jpg'

Thank you again and I apologize for my very newbie questions.
steeve88 wrote:
I use the command below, but when I run my function, a message says that a picture name expected. The name of the picture is 1235.jpg and it also exists in data browser. What should be wrong here?

newmovie /F=1/P=IgorSpace/PICT='1235.jpg'


I suggested that you start by loading the first image and then displaying it as a graph. Only then you should execute the newmovie command. In that case, when you execute the newmovie command you have an image displayed in a front graph so you do not need the /PICT flag. So your code will look something like:
ImageLoad ...
NewImage/S=0 ...   // this gives you a top graph that displays the image
NewMovie/F=1/P=IgorSpace  // No other arguments here
// now loop over the images
...


Hello again.

After the afore-mentioned instructions I managed to create this code that creates a video using images:

Function Igor_movie_from_picture(fileStr)
    string fileStr    //this connects the above parenthesis with the type of images that will be loaded, ie. (".jpg")

    Newpath/O IgorSpace, "C:\Users\Public\Documents\Wavemetrics\IgorSpace"   //Here I have my satellite images
   
    print indexedDir(IgorSpace,0,0)     //Prints the path
   
    variable i,j
   
    string fileListString = indexedfile(IgorSpace, 0, fileStr)  //declare the fileListstring as string variable, which contains all the images of the directory - -1 is for means that all files of type 'fileStr' will be used
   
    print fileListString      //content of IgorSpace appears
       
    imageload /O/P=IgorSpace /T=fileStr fileListString   //Load the image
   
    Wave/Z w=$StringFromList(0,fileListString)    //creates a wave that contains the first image from the fileliststring
       
    newimage /N=SatSet /S=0 w     //creates a graph which contains the loaded image
   
    newmovie /O/F=1/P=IgorSpace   //creates movie file which contains the first image
   
    doupdate
   
    fileListString = indexedfile(IgorSpace, -1, fileStr)
   
    j=itemsinlist(fileListString) //so for loop will operate j times (as the number of the files that will be loaded
   
   
    for (i=1;i<j;i+=1)
   
        fileListString = indexedfile(IgorSpace, i, fileStr)   //each picture is assigned into fileliststring
       
        print fileListString
       
        imageload /O/P=IgorSpace /T=fileStr fileListString
       
        wave w=$StringFromList(i,fileListString)
       
        print w
       
        newimage /N=SatSet /S=0 w
       
        DoUpdate
       
        addmovieframe
   
    endfor
   
   
    closemovie

end




The problem is that when I try to run this program, a message says "expected wave name" refering to the command newimage. I have declared the wave w, but i cannot understand why a message like that appears. Additionally, the command print w inside for loop gives a null wave instead of a wave that contains the images for video.

Are there any ideas?
The problem is in the loop:

wave w=$StringFromList(i,fileListString)


at that time fileListString is not a list anymore and the index i > 0 does not exist.

Something like this should probably do it:
Function Igor_movie_from_picture(fileStr)
    string fileStr    
    Newpath/O IgorSpace
 
    variable i,j
   
    string fileListString = indexedfile(IgorSpace, -1, fileStr)  //declare the fileListstring as string variable, which contains all the images of the directory - -1 is for means that all files of type 'fileStr' will be used
    print fileListString
    j=itemsinlist(fileListString) //so for loop will operate j times (as the number of the files that will be loaded
 
    for (i=0;i<j;i+=1)
       
        string nextImage = StringFromList(i, fileListString)
       
        imageload /O/P=IgorSpace /T=fileStr nextImage
        wave w=$nextImage
        newimage /N=SatSet /S=0 w
       
        // open movie; only required for i==0
        if (i==0)
            newmovie /O/F=1/P=IgorSpace   //creates movie file which contains the first image
        endif
 
        DoUpdate
        addmovieframe
 
        DoWindow/K SatSet
    endfor
 
    closemovie
end

In reply to by ChrLie

Hi,

I found this forum relevant to make a video of my images that I loaded as image file in jpg format. However it fails to run this code. Basically I created a folder called IgorSpace and loaded every images in it on my experiment file. Whenever I run the code, it asks me select a folder, however after selecting the folder that has images, it does not match the selection and says "attempted to access a null string variable". A quick search help topic says that is StringFromList should have a list of text items. I created a table of textwave with names of all images but that did not work too. I must have misunderstood some basic stuff. Can anyone suggest me?

Thank you in advance !

In reply to by TRK

1. folder does not have to have a specific name, the code asks you to select it

2. you don't need to load images into experiment, the code does that

3. are you executing Igor_movie_from_picture("jpg")?

In reply to by tony

Well, now the code gets executed but when I select the folder that has jpg files, it returns an error saying that unsupported image format. But it only creates a Tempmovie file with a graph on my experiment file. 

Also what is "." doing in the execution command. I was thinking of something $ for the string.

filestring, the input to the function, is a string that is used as a parameter for the IndexedFile function.

DisplayHelpTopic "IndexedFile"

to see what IndexedFile is expecting to find in the string.

filestring is later used with ImageLoad to specify the file type. Here it must be "jpeg", not ".jpg". So try that instead.

Thanks Tony, well this time it displays this error. "While executing CloseMovie, the following error occurred: No movie"

Looking for the explanation on close movie did not help to fix this

if there is no list of files printed to history and you weren't prompted to save a movie file, indexedfile is not listing the jpegs.

for a quick solution, try hardwiring the code for jpegs, something like this:

function Igor_movie_from_JPGs()
 
    variable i,numFiles
    string fileListString, nextImage
   
    NewPath/O PathToJPGs
    NewMovie /O/F=1/P=PathToJPGs
   
    fileListString = IndexedFile(PathToJPGs, -1, ".jpg")  //declare the fileListstring as string variable, which contains all the images of the directory - -1 is for means that all files of type 'fileStr' will be used
    numFiles=ItemsInList(fileListString)
    for (i=0;i<numFiles;i+=1)
        nextImage = StringFromList(i, fileListString)
        Print "loading " + nextImage
        ImageLoad /O/P=PathToJPGs/T=jpeg nextImage
        wave w=$nextImage
        NewImage /N=tempImage /S=0 w
        DoUpdate
        AddMovieFrame
        DoWindow/K tempImage
    endfor
    CloseMovie
    KillPath /Z PathToJPGs
end