imshow in GUI too slow

Hello, I've made a GUI that displays a series of images (250x500, jpg) in a portion (usually 5-10) of 36 existing axes. The axes are in a special pattern (so can not use montage) and sometimes overlapping. I am using IMSHOW to match images with axes (and imshow with blank images to erase the axes). These get updated about every 3-5 seconds, but take 2-3 seconds to display. I would like to make it display as fast as possible.
I've experimented using IMAGESC instead, but it has not sped this up at all. I've tried all three renderers and put direct buffering to no avail.
I read a very old post that reccomended not changing the image on each axis, but rather keeping the image and changing the image data using set(himage, 'CData', newdata) where new data is your MxNx3 uint8. So that I would store the images as a matrix and only update the image data. I tried this but it wouldn't cooperate with how I've written my parent code.
Although I think this may work, it would take a week to reconstruct the parent code. Are there any other methods I can try to avoid this?

 Accepted Answer

If performance is critical, you would do well to refresh the images via setting the 'CData' of each existing image handle rather than taking the performance hit of input parsing in imshow/imagesc and the performance hit of needing to recreate an HG image object each time you want to refresh an image.
If you are using subplot to layout the axes within your figure, you should be aware that subplot returns a handle to the axes being created/accessed.
hAxes = subplot(1,1,1);
hImage = imshow('pout.tif','Parent',hAxes);
Once you have created an HG image in a given axes using imshow, you can now refresh the 'CData' of the image object.
set(hImage,'CData',rand(200,200,3));
Note that if the size of the image data has changed, you will see alignment issues with your axes, there is no management of the position of the axes when you refresh the 'CData'.
This is all there is to what you're trying to do.

4 Comments

curran
curran on 27 Apr 2012
Its not subplot, its a GUI, but the same applies. I had seen this solution from a few years ago but didn't think it would fit in with how I wrote the original script, i.e. calling the GUI everytime I refresh it (I am not familiar with how gui_mainfcn works).
Obviously the GUI stays open when I am running the parent file, so when I recall the GUI, all of the handles stay the same? Then I can just query if an image exists in the axis, or initialise with an image and change the data?
curran
curran on 27 Apr 2012
Sorry, a GUI I built in GUIDE, I suppose you could have a GUI with a subplot, but GUIDE only allows for independent axes from what I can see.
Ah, I mixed up Image Analyst's comments about subplot with your original post. My mistake. My original comment still applies, it's just a matter of laying out the figure/axes once and then refreshing the 'CData' as you need to, as you've pointed out.
curran
curran on 3 May 2012
Just an update, it increased performance about 12x
Crazy... thanks.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 26 Apr 2012

0 votes

Have you used the profiler to see that it's imshow that's the bottleneck and not imread or some other code?

8 Comments

curran
curran on 26 Apr 2012
Yup, besides user input waiting time, IMSHOW is 85% of the comp time.
You aren't calling imshow() a bunch of times on the same axes are you? If you are, you can call cla reset before each one to speed it up. But it sounds like only one image is going into each axes, but I'm not sure what you mean by overlap. You mean like one axes control is partially on top of another?
curran
curran on 27 Apr 2012
Yes, the axes are overlapping spatially, which only proves to be a visibility problem sometimes, but thats a different issue I think I can address when I get the speed figured out. I had seen you commented on someone else's question about the cla reset, but you are right, there is only one image per set of axes.
I had the script written in text-based format and wanted to install the GUI on top of it. Everytime I wanted to update the GUI, I would just call it again and it would update. When it went slow, I assumed it was just my bad form of calling it over and over, but it turned out to be imshow.
Can you make up some code to generate a set of 36 250x500 images and display them and see how long it takes? Does it happen with the sample code, or just your code?
curran
curran on 27 Apr 2012
So using:
figure(2)
A = imread('province.jpg');
for i=1:36
subplot(6,6,i)
imshow(A)
end
I get:
Profile Summary
Untitled2 1 4.262 s 0.359 s
imshow 36 3.206 s 0.531 s
This is what I get:
test 1 call 0.749 s 0.102 s
imshow 36 call 0.396 s 0.043 s
That's 10 times faster than your computer. But your times are like 10 times faster than what you said. You said it takes as long as 5 seconds to display an image but your profiler shows 0.5 seconds. Maybe there's something going on in your computer that I just can't replicate.
curran
curran on 1 May 2012
Mmm, sorry no, it wasn't per image, it was for all the entire GUI. I guess I'll live with it.
So was mine. It was for 36 images, not just one image. See where it says "imshow 36" in my message. That means it was called 36 times, just like yours.
You don't have to live with it. Perhaps you just need a newer computer, like mine.

Sign in to comment.

Categories

Find more on Environment and Settings in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!