Image processing automation

I am a new user and I am trying to automate the following tasks:

1. from an existing AVI video file, I wish to load the individual frames

2. for each individual frame, I wish to define a region of interest (ROI)- same area and location on each frame

3. for each ROI, I wish to obtain a line profile, by using the ImageLineProfile operation and I wish to store the (x,y) data as a column vector on a larger MxN matrix

4. for each (x,y) data, column vector, I wish to do a “gauss” fit and save the results, y0, A, x0, width as a column vector of a new MxN results matrix


Although, I am able to step-wise perform each and every step of the process describer above. Creating an automated script/macro or Procedure that would accomplish the same result appears to be beyond my capability as of now. I am still trying to learn how to define, create and run Procedures.

Thanks very much in advance for any help on this task.

Carl
For at least some of this, your step-by-step manual processing must have generated some command lines that would serve as a starting point. Things that involve the Image Analysis control panels (or most control panels, for that matter) you may not have the commands that were used to do the work.


cav_igor wrote:
1. from an existing AVI video file, I wish to load the individual frames

Look at PlayMovie and PlayMovieAction.
Quote:
2. for each individual frame, I wish to define a region of interest (ROI)- same area and location on each frame

ImageGenerateROIMask
Quote:
3. for each ROI, I wish to obtain a line profile, by using the ImageLineProfile operation and I wish to store the (x,y) data as a column vector on a larger MxN matrix

Do you really need the ImageLineProfile operation? Are the profiles rows or columns from the 2D wave? If so, you just need to extract a row or column, you don't really need ImageLineProfile.
Quote:
4. for each (x,y) data, column vector, I wish to do a “gauss” fit and save the results, y0, A, x0, width as a column vector of a new MxN results matrix

Ah- my area of expertise...
To get you started, here's a function that will fit a gaussian peak to each column of a 2D wave:
Function FitGaussToImageColumns(image)
    Wave image
   
    Variable ncols = DimSize(image, 1)
    Variable i
   
    Make/O/D/N=(ncols, 4) $(NameOfWave(image)+"gauss")/WAVE=output
   
    for (i = 0; i < ncols; i += 1)
        CurveFit/N/Q/W=2 gauss, image[][i]
        WAVE W_coef
        output[i][] = w_coef[q]
    endfor
end

If you have programmed before, you should recognize the loop. The Make command has some complexity because it makes an output wave with a name derived from the name of the input image (note that you have to be careful not to use very long names for your image waves). The WAVE flag makes a "wave reference"- that's a symbolic way to refer to a wave in a function. It has two purposes- at compile time it establishes a name that the compiler subsequently knows to be a wave, so it can compile wave code for that name. At run-time it actually looks for a wave with that name. In the case of the Make command, it creates a wave reference pointing to the new wave. In this case, you don't know the name at compile time, so you need a symbolic name for it. Later, there is a WAVE statement to connect to the W_coef wave that's created by the CurveFit command.

Note the sub-range syntax used CurveFit. Unless you need line profiles at an angle, or profiles that average across some width of the image wave, you don't need ImageLineProfile.

If your ROI isn't rectangular, it may be tricky to come up with the sub-range you need for each fit. But if you have an ROI mask wave, you can probably use it with the /M parameter flag with CurveFit. To get started with learning Igor programming, I would read chapters 1,2,3,5 and 7 of the Programming manual. Unless you're very unusual, you won't get it the first time through. But if you keep trying to write code, and re-reading the manual, it will eventually become less frustrating.

Good luck!

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
I would be interested in seeing a code snippet on how to open an AVI and extract a frame, using PlayMovieAction. I am encountering various RTE syntax problems with that operation. Among other issues its keyword 'ref = ' does not appear in green in my procedure code, which compiles without error.

IP 6.12A, Win VISTA

Stephen R. Chinn
John,

Thank you very much for all your suggestions and general advice.

As you have guessed, the required ROI is not a simple square or rectangle, but a more complicated geometry. Therefore, the profiles are not simple rows or columns from a 2D wave. As such, the only way that I have been able to extract any useful data is to use the ImageLineProfile operation.

As to the "fit" Function, I will code-up and run your code using some simple data just to familiarize myself with its operation. This part of the process will significantly help my Image Processing Automation.

Again, many thanks for all your assistance.
Carl
cav_igor wrote:
As you have guessed, the required ROI is not a simple square or rectangle, but a more complicated geometry. Therefore, the profiles are not simple rows or columns from a 2D wave. As such, the only way that I have been able to extract any useful data is to use the ImageLineProfile operation.

I'm not sure exactly how you're using the ImageLineProfile operation for this, but maybe there's another way. I don't know a lot about the image processing commands (I'm the curve fitting guy) but I think one output from an ROI can be a matrix wave with 1's and 0's to mark pixels as being inside or outside the ROI. That ROI wave could be used with the code I posted above to make a mask for the fit.
Function FitGaussToImageColumns(image, roiwave)
    Wave image
    Wave roiwave
   
    Variable ncols = DimSize(image, 1)
    Variable i
   
    Make/O/D/N=(ncols, 4) $(NameOfWave(image)+"gauss")/WAVE=output
   
    MatrixOP/O columnSums = sumCols(roiwave)^t
    for (i = 0; i < ncols; i += 1)
   
        if (columnSums[i] > 4)
            CurveFit/N/Q/W=2 gauss, image[][i]/M=roiwave[][i]
            WAVE W_coef
            output[i][] = w_coef[q]
        endif
    endfor
end

Note that the main changes I've made are an additional input to pass in an ROI wave, plus the addition of the /M flag referencing a column of the ROI wave. I also added the MatrixOP command to discover which columns have enough points inside the ROI to be fit successfully.

It would be possible to remove the roiwave input and add code to generate the ROI wave. But it would probably be better to keep the roiwave input, and write a separate function to generate the ROI. That keeps things modularized in a way that makes it easier to change bits of the program when you need to.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com