Speeding Up A Function
ctmckee
I want to speed up the time required to process the following function, which runs through a list of images and creates an ROI boundary for each image that is seed filled. I suspect that the main speed component is associated with the size of the image file (#number of pixels), however maybe something else about the loop is also slowing it down. Any suggestions. Thanks
function makeROIContour(imagename)
wave imagename
wave m_roimask
string XL,YL,xwavelist,ywavelist,M
variable H,W,Index
xwavelist=wavelist("*x",";","")
ywavelist=wavelist("*y",";","")
H=dimsize(imagename,0)+69
W=dimsize(imagename,1)+71
M=num2str(index)
do
XL = stringfromlist(index,xwavelist,";")
YL = stringfromlist(index,ywavelist,";")
if(strlen(XL) == 0)
break
endif
imageboundarytomask width=h,height=w,xwave=$XL,ywave=$YL,seedX=0,seedy=0
string xw="xROI"+M
duplicate/o M_roimask, $XW
index+=1
m=num2str(index)
while(1)
end
wave imagename
wave m_roimask
string XL,YL,xwavelist,ywavelist,M
variable H,W,Index
xwavelist=wavelist("*x",";","")
ywavelist=wavelist("*y",";","")
H=dimsize(imagename,0)+69
W=dimsize(imagename,1)+71
M=num2str(index)
do
XL = stringfromlist(index,xwavelist,";")
YL = stringfromlist(index,ywavelist,";")
if(strlen(XL) == 0)
break
endif
imageboundarytomask width=h,height=w,xwave=$XL,ywave=$YL,seedX=0,seedy=0
string xw="xROI"+M
duplicate/o M_roimask, $XW
index+=1
m=num2str(index)
while(1)
end
Instead of
Duplicate
, you can also move M_roimask withRename
.How long does it take now and what is the target duration?
Btw. your strlen check should also check for YL to be on the safe side.
This is definitly something you can speed up with writing threaded code, but as this is bit more involved, I would put that at the end of the things-to-try-list.
September 29, 2014 at 11:32 am - Permalink
Hi Thomas,
The length of the wavelist is less than 50. And it currently takes 15 seconds to complete the loop, this seems very long.
Also, to be more accurate, the wavelists (x and y) are contour traces from an image, which I want to fill in using the imageboundarytomask and seed fill.
I tried the Rename instead of duplicate...this results (at end of loop) in creating a single wave which is named after the final instance of the $XW at the end of the loop (and no time save).
Cheers,
Clayton
September 29, 2014 at 12:38 pm - Permalink
A.G.
WaveMetrics, Inc.
September 29, 2014 at 12:47 pm - Permalink
Thanks,
clayton
September 29, 2014 at 12:55 pm - Permalink
A.G.
September 29, 2014 at 03:12 pm - Permalink
1st - Define a number of z contours for an image.
2nd - Extract the X and Y contour traces to a folder
3rd - Fill each contour by conducting ImageBoundaryToMask and then ImageSeedFill.
4th - Perform ImageAnalyzeParticles on the SeedFill images to define objects at each plane of the contour
5th - Implement some conditional statements to throw away things which are not objects of interest (see attached figure2).
The 3rd step above is very slow and I'm trying to figure out how to speed it up.
September 29, 2014 at 03:45 pm - Permalink
I am not a big fan of your approach. It is not clear to me how you define contours. Looking at your sample I noticed that several blobs had more than one contour which is clearly not desirable.
I confess I do not understand much about gel analysis but I am familiar enough with the pictures to note that many of the blobs are not exactly rectangles. Before we go any further, have you considered running simple particle analysis? The idea is that for any threshold level, you may consider each one of your rectangles as a particle whose center of mass can be determined and where the fitting ellipse would give you both the width and length of the blob. In fact, you can use the fitting ellipse to generate a pretty good matching rectangle to synthesize the image from a limited set of parameters.
A.G.
September 30, 2014 at 02:05 pm - Permalink
Agreed, having more than one contour is undesirable for a single "blob" object; what you're seeing in that image is all the instances (as a function of defined contours in the z direction) where the object is more rectangular than circular (the final bit of code would need to remove repeat instances of a found object with some argument for when a band is....."full"). In this sense, it's analogous to your to suggestion to run particle analysis and "that for any threshold level, you may consider each one of your rectangles....."
In my case, I was trying to get around the problem that several of the objects are not exactly rectangles (as you noted) and that if you try to analyze the image using a single threshold you find things which are not bands. So, I tried to analyze the image as a function of filled z contour traces, in this case, objects which are non rectangular when viewed for the full z-range, are rectangles (and become more or less rectangular) as they approach their peak intensities. I guess, a loop that runs through every threshold level (0-255) and conducts imageanalyzeparticles will achieve the same goal (using appropriate conditional statements for object removal). I'm assuming based on your response, that this will be faster; however, I will still need to address the issue of removing objects that are found more than once with a bit of logic to determine if the band is "full" at a given threshold. I'll right it up and give it a go.
Thanks
Clayton
October 1, 2014 at 09:59 am - Permalink
I'd describe the objects that do not appear rectangular as "smeared". Regardless of the process that gives rise to this image, you can pick some threshold value that yields a particle at a position that is pretty close to the center of the blob. If your goal is to find an exact representation for the blob you could use some approximation (fit to ellipse which I mentioned before) or if the intensity profile is really important to you, I see no reason why you can't extract the original data around the blob into a 2D wave and use curve fitting to obtain an "optimal" rectangle representation. Again, I do not know your application so I'm not sure this extra effort is worthwhile.
I'd also note that in many instances a completely different approach may yield (efficiently) most of the relevant information. If you open the Image Processing Tutorial you will find in section 5 example of locating objects using correlations. In your application I would try to correlate your images with a small rectangle. Execute ImageThreshold on the result and you will obtain correlation spots at the centers of the matching rectangles. The shape of the 2D correlation peaks can be used to analyze the dimensions of the rectangles.
A.G.
WaveMetrics, Inc.
October 1, 2014 at 10:44 am - Permalink