Automating Image Analysis
isk8
I have to extract RGB profiles from n number of images, and for a single image analysis, and I've written a code that looks like the following:
Function RGB_Profile()
ImageLineProfile/P=-2 srcWave=image, xWave=coord_x, yWave=coord_y, width=1 //Get R,G,B line profiles from a ROI in an image using coordinates "x_coord", "y_coord" obtained from graph marquee
Make/N=(numpnts(M_ImageLineProfile)/3) pixel_x //M_ImageLineProfile contains 3 columns of data for R, G, B. make a wave with the same number of points required for position calibration
Redimension/N=(numpnts(M_ImageLineProfile)) M_ImageLineProfile //Combine 3 columns into 1 column
Duplicate/R=(0,(numpnts(pixel_x)-1)) M_ImageLineProfile, profileR //extract profile R from M_ImageLineProfile
Duplicate/R=((numpnts(pixel_x)), (numpnts(pixel_x)*2-1)) M_ImageLineProfile profileG //extract profile G from M_ImageLineProfile
Duplicate/R=((numpnts(pixel_x))*2, (numpnts(pixel_x)*3-1)) M_ImageLineProfile profileB //extract profile B from M_ImageLineProfile
pixel_x=x+(coord_x[0]) //calibrate actual pixel position with no. of rows in profiles R, G, and B
Display profileR profileG profileB vs pixel_x
ModifyGraph rgb(profileG)=(0,65280,0),rgb(profileB)=(0,0,65280)
ImageLineProfile/P=-2 srcWave=image, xWave=coord_x, yWave=coord_y, width=1 //Get R,G,B line profiles from a ROI in an image using coordinates "x_coord", "y_coord" obtained from graph marquee
Make/N=(numpnts(M_ImageLineProfile)/3) pixel_x //M_ImageLineProfile contains 3 columns of data for R, G, B. make a wave with the same number of points required for position calibration
Redimension/N=(numpnts(M_ImageLineProfile)) M_ImageLineProfile //Combine 3 columns into 1 column
Duplicate/R=(0,(numpnts(pixel_x)-1)) M_ImageLineProfile, profileR //extract profile R from M_ImageLineProfile
Duplicate/R=((numpnts(pixel_x)), (numpnts(pixel_x)*2-1)) M_ImageLineProfile profileG //extract profile G from M_ImageLineProfile
Duplicate/R=((numpnts(pixel_x))*2, (numpnts(pixel_x)*3-1)) M_ImageLineProfile profileB //extract profile B from M_ImageLineProfile
pixel_x=x+(coord_x[0]) //calibrate actual pixel position with no. of rows in profiles R, G, and B
Display profileR profileG profileB vs pixel_x
ModifyGraph rgb(profileG)=(0,65280,0),rgb(profileB)=(0,0,65280)
I have already loaded n number of images named, image1, image2 and etc., and I'm trying to automate this analysis for all images in sequence, and I was wondering what the simplest way is to do this.
Thank you for the help!
Wave imageWave,coord_x,coord_y
...
End
Next, you should ask yourself if you really want to display the results or just store them for display later. In both cases your function should be modified so that the "output" waves (profileR, profileG, profileB and pixel_x) are not overwritten by subsequent calls to your function. One way to accomplish this is to store the result of each run in a dedicated data folder:
Wave imageWave,coord_x,coord_y
DFREF saveDFR = GetDataFolderDFR() // Save old df
NewDataFolder/O/S someDFName // create new df
... // do your work here
SetDataFolder saveDFR // and restore
End
The choice of someDFName needs to be unique. One way to generate it is:
where index is a count for the image that you are processing.
The next part to handle is your "image sequence". If your images are already loaded into the experiment you could create a string list using WaveList() from which you sequentially pick up an image for processing. If your images are not already loaded (say they are stored on a disk file) you can use IndexedFile() (see, for example http://www.igorexchange.com/node/537).
Finally, your code for extracting the three components is more complex than necessary:
Duplicate/R=(0,(numpnts(pixel_x)-1)) M_ImageLineProfile, profileR //extract profile R from M_ImageLineProfile
Duplicate/R=((numpnts(pixel_x)), (numpnts(pixel_x)*2-1)) M_ImageLineProfile profileG //extract profile G from M_ImageLineProfile
Duplicate/R=((numpnts(pixel_x))*2, (numpnts(pixel_x)*3-1)) M_ImageLineProfile profileB //extract profile B from M_ImageLineProfile
I'd replace it with:
MatrixOP/O profileR=col(M_ImageLineProfile,0)
MatrixOP/O profileG=col(M_ImageLineProfile,1)
MatrixOP/O profileB=col(M_ImageLineProfile,2)
I hope this helps,
A.G.
WaveMetrics, Inc.
November 21, 2012 at 02:53 pm - Permalink
String list=ImageNameList("", ";")
String imageName
String currentWave
Variable index = 0
Wave coord_x, coord_y
do
imageName = StringFromList(index, list)
if(strlen(imageName) == 0)
break // No more images
endif
String DFName = "image"+num2str(index)
DFREF saveDFR = GetDataFolderDFR() // Get reference to current data folder
NewDataFolder/O/S $DFName // Make folder named image"i"
Variable i = 0
do
currentWave = StringFromList(i, list)
if(strlen(currentWave) == 0) // No more images
break
endif
String imageWave = "image"+num2str(i)
Wave w = $imageWave
ImageLineProfile/P=-2 xWave=root:coord_x, yWave=root:coord_y, srcWave=$imageWave, width=1 // ImageLineProfile for image"i"
Make/N=(numpnts(M_ImageLineProfile)/3) pixel_x
Wave M_ImageLineProfile
MatrixOP/O profileR=col(M_ImageLineProfile,0)
MatrixOP/O profileG=col(M_ImageLineProfile,1)
MatrixOP/O profileB=col(M_ImageLineProfile,2)
pixel_x=x+(coord_x[0])
Display profileR profileG profileB vs pixel_x
ModifyGraph rgb(profileG)=(0,65280,0),rgb(profileB)=(0,0,65280)
i += 1
while (1)
index += 1
while (1)
SetDataFolder root: // Set current data folder back to root folder
End
I've already loaded my images (named image0, image1, etc.) and I will be using the same coord_x & coord_y (in the root folder) for all images.
When I try to execute the function, I get the following error message:
"While executing ImageLineProfile, the following error occurred: One or more of the input waves are not supported."
I think "srcwave=$imageWave" is causing the problem, but I don't seem to be able to figure out what's wrong.
Do you have any idea why?
Thank you for the help!
November 28, 2012 at 12:54 am - Permalink
This error can occur for two reasons:
1) Igor didn't find one or more of the x, y, or src waves that you specified (for example, ImageLineProfile was called with a NULL srcWave wave).
2) One or more of the x, y, z waves is a text wave (contains text instead of numbers).
The second option is unlikely. A potential culprit is indeed that Igor cannot find the wave in the
srcwave=$imageWave
statement.I would go about diagnosing this using the debugger (execute
DisplayHelpTopic "The Debugger"
if this extremely valuable tool doesn't ring any bells). Right-click somewhere in your procedure window, and select "Enable Debugger" if it isn't checked already. Next click in the margin next to theWave w = $imageWave
line, run your function, and watch what happens when you execute the statement (using the 'step over' instruction in the upper left-hand side of the debugger window). Is w NULL after this statement executes? Then that is your problem.The debugger usually is your best friend in situations such as these.
November 28, 2012 at 02:39 am - Permalink
1. What is the role of currentWave?
2. If you already have imageName why are you executing:
Wave w = $imageWave
and not
Wave w = $imageName
Also, you may find it better to use Wave/Z and then test:
ImageLineProfile/P=-2 xWave=root:coord_x, yWave=root:coord_y, srcWave=w, width=1 // ImageLineProfile for image"i"
endif
I hope this helps,
A.G.
WaveMetrics, Inc.
November 28, 2012 at 10:43 am - Permalink
As you mentioned, I also think 2) is unlikely because I've already defined them as waves. Also, if I just type in "ImageLineProfile" function with image0 instead of $imageWave, it works.
I've tried this, but w is not NULL. In fact, it is image0, which is the correct src wave.
This is really strange, because as mentioned above, if I manually type in image0 in the place of $imageWave the function works.
But, if image0 is replaced with $imageWave, the function keeps on giving me the same error.
I'd really appreciate if there are any other suggestions.
Thank you.
November 28, 2012 at 11:18 am - Permalink
The error message that you are reporting is returned when any one of xwave, ywave or srcwave are not appropriate for ImageLineProfile. If you run the code I suggested under the debugger you should be able to check if both xwave and ywave are real numeric waves and that w is a 3D numeric wave.
November 28, 2012 at 11:39 am - Permalink
I forgot to specify the folder where the src wave is located.
Thanks again.
November 28, 2012 at 12:56 pm - Permalink