If I've multiple axes on my Matlab GUI window, and each one of them has a different image.
How can I manage to do roipoly function on each of them ?
This solution should be without recalling imshow then roiploy after it for each one of them since:
All images are show on axes using a loop that if I processed axes one after one the GUI would appear so ugly.
Re-doing imshow will cost time as images are very large and they are processed each time before being shown, so it'll be a ver bad solution to waste time in a repeated processing.
Use impoly instead of roipoly:
polyH = impoly( hAxes );
position = wait( polyH );
Please see Matlab's doc on impoly for more functionality.
Related
I am want to draw once, and then update (very) often and redraw (less) often an image in MATLAB. My image is a vector which is updated and redrawn. To show this image, I used I = imagesc(reshape(data, nVoxels)) to draw and I.CData(:) = data to update. (Redrawing is taken care of seperately.) This worked fine.
Now, in order to make the correspondence to an x-y-coordinate system (x horizontal, y vertical - very standard), where the first dimension of reshape(data, nVoxels) is x and the second is y, I need to draw like this:
I = imagesc(reshape(data, nVoxels)');
axis('xy');
But how can I make a quick update of the image data now?
So far, I have found I need to do
I.CData = reshape(data, nVoxels)';
but I would prefer to do something like before, updating CData without having to reallocate and without having to transpose the data.
Is that possible? I am specifically interested in updating very often in a loop; redrawing is handled independently using a timer.
The transpose can be avoided by setting x and y limits when you create the image to flip it, and rotating the axes:
I = imagesc([nVoxels(2) 1], [1 nVoxels(1)], reshape(data, nVoxels));
camroll(90);
then using
I.CData(:) = data;
again.
However, the transpose time is probably negligible compared to updating the figure using drawnow().
I'm building a data analysis platform in MATLAB. One of the system's features need to create many plots. At any given time only one plot is available and the user can traverse to the next/previous upon request (the emphasis here is that there is no need for multiple windows to be open).
Initially I used the figure command each time a new plot was shown, but I noticed that, as the user traverse to the next plot, this command took a bit longer than I wanted. Degrading usability. So I tried using subplot instead and it worked much faster.
Seeing this behavior I ran a little experiment, timing both. The first time figure runs it takes about 0.3 seconds and subplot takes 0.1 seconds. The mean run time for figure is 0.06 seconds with standard deviation of 0.05, while subplot take only 0.002 with standard deviation of 0.001. It seems that subplot is an order of magnitude faster.
The question is: In situation when only one window will be available at any given time, is there any reason to use figure?
Is there any value lost in using `subplot' in general?
(similar consideration can be made even if you can either only once).
The call of subplot does nothing else than creating a new axes object with some convenient positioning options wrapped around.
Axes objects are always children of figure objects, so if there is no figure window open, subplot will open one. This action takes a little time. So instead of opening a new figure window for every new plot, it's faster to just create a new axes object by using subplot, as you determined correctly. To save some memory you can clear the previous plot by clf as suggested by Daniel.
As I understood, you don't want to Create axes in tiled positions, rather you just want to create one axes object. So it would be even faster to use the axes command directly. subplot is actually overkill.
If all your plots have the same axes limits and labels, even clf is not necessary. Use cla (clear axes) to delete the previous plot, but keep labels, limits and grid.
Example:
%// plot #1
plot( x1, y2 );
xlim( [0,100] ); ylim( [0,100] );
xlabel( 'x' );
ylabel( 'y' );
%// clear plot #1, keep all settings of axes
%// plot #2
plot( x2, y2 );
...
Use figure once to create a figure and clf to clear it's content before repainting.
I am currently working on a project that is utilizing traffic camera video streams and analyzing them. I have written an algorithm in Octave, a .m file, that is able to return the outlines of multiple cars as individual blobs, and its outline and center coordinates. Specifically, for the blob part, I am using BWLabel and BWBoundaries and applying it to a binary image that I have created where 1 is car and 0 is background, according to the rest of my algorithm. I have an image below that shows this.
http://imgur.com/25hgrUP
All of the blobs are cars, including the one with about 5 blobs next to each other. All of these blobs are one van, but the different colors and features have thrown off the detection system. Does anyone know of a way to easily combine all of these blobs that are in close proximity into one blob. I am talking about an existing algorithm or function that is already in Octave packages or Matlab toolboxes. If not, I will write the code from scratch and make it happen. This question was just a call to ask if there are pre-existing solutions, not a call to write code for me, unless you want to :).
Thanks for your help,
AeroVTP
You can solve this (to an extent) with morphological closing, in Matlab it's imclose. You'll need to be careful, though as noise that's too close may be included, and true blobs too far away may be excluded.
Although imclose is a good idea, running it just one time has a much "stronger" effect on the image than just running the 'erode' and 'dilate' functions multiple times. I personally ran the erode and dilate functions 5 times, in succession, to get the best results for the earlier image. Running the Dilate and Erode commands separately give more control for good image processing.
Imclose is just a function that applies the erode and dilate functions repeatedly. In Octave, the function to dilate and erode is
editedImage = bwmorph(initialImage, 'dilate', 5 %number of times to apply% );
editedImage = bwmorph(initialImage, 'erode', 5 %number of times to apply% );
I also invented my own commenting structure :).
Thanks to wbest for initial imClose idea.
I finally solved my problem here with lennon310.
I have a picture of thousands of thin peaks in Time-Frequency picture.
I cannot see all the same time in one picture.
Depending on the physical width of my time window, some windows appear and some come visible.
Pictures of my data which I plot by imagesc
All pictures are from the same data points T, F, B.
How can you plot all peaks at once in a picture in Matlab?
You need to resize the image using resampling to prevent the aliasing effect (that craigim described as unavoidable).
For example, the MATLAB imresize function can perform anti-aliasing. Don't use the "nearest" resize method, that's what you have now.
Extension to #BenVoigt's answer
My try
B = abs(B);
F1 = filter2(B,T); % you need a different filter kernel because resolution is lower
T = filter2(B,F);
F = F1;
image1 = imagesc(B);
display1 = imresize(image1, [600 600], 'bilinear');
imshow(T*t, F*fs, display1);
where are some problems.
I get again picture where the resolution is not enough
2nd Extension to BenVoigt's answer
My suggestion for one kernel filter is with convolution of relative random error
data(find(data ~= 0)) = sin(pi .* data(find(data ~= 0))) ./ (pi*data(find(data ~= 0)));
data(find(data == 0)) = 1; % removing lastly the discontinuity
data1 = data + 0.0000001 * mean(abs(data(:))) * randn(size(data));
data = conv(data, data1);
Is this what BenVoigt means by the kernel filter for distribution?
This gives results like
where the resolution is still a problem.
The central peaks tend to multiply easily if I resize the window.
I had old code active in the above picture but it did not change the result.
The above code is still not enough for the kernel filter of the display.
Probably, some filter functions has to be applied to the time and frequency axis separately still, something like:
F1 = filter2(B,T); % you need a different kernel filter because resolution is lower
T = filter2(B,F);
F = F1;
These filters mess up the values on the both axis.
I need to understand them better to fix this.
But first to understand if they are the right way to go.
The figure has be resized still.
The size of the data was 5001x1 double and those of F and T 13635x1 double.
So I think I should resize lastly after setting axis, labels and title by
imresize(image, [13635 13635], 'bilinear');
since the distirbution is bilinear.
3rd Extension to BenVoigt's answer
I plot the picture now by
imagesc([0 numel(T)], [0 numel(F)], B);
I have a big aliasing problem in my pictures.
Probably, something like this should be to manipulate the Time-Frequency Representation
T = filter2(B,t); % you need a different filter kernel because resolution is lower
F = filter2(B,fs);
4th extension to BenVoigt's answer and comment
I remove the filters and addition of random relative errors.
I set the size of T,F,B, and run
imagesc([0 numel(T)], [0 numel(F)], B, [0 numel(B)])
I get still with significant aliasing but different picture
This isn't being flippant, but I think the only way is to get a wider monitor with a higher pixel density. MATLAB and your video card can only show so many pixels on the screen, and must decide which to show and which to leave out. The data is still there, it just isn't getting displayed. Since you have a lot of very narrow lines, some of them are going to get skipped when decisions are made as to which pixels to light up. Changing the time window size changes which lines get aliased away and which ones get lucky enough to show up on the screen.
My suggestions are, in no particular order: convolute your lines with a Gaussian along the time axis to broaden them, thus increasing the likelihood that part of the peak will appear on the screen. Print them out on a 600 dpi printer and see if they appear. Make several plots, each zooming in on a separate time window.
3rd Extension to BenVoigt's answer
My attempt to tell imagesc how big to make the image, instead of letting to use the monitor size, so it won't away data.
imagesc(T*t, F*fs, B, [50 50]);
% imagesc(T*t, F*fs, B');
% This must be last
imresize(image, 'bilinear', [64 30],);
I am not sure where I should specify the amount of pixels in x-axis and y-axis, either in the command imagesc or imresize.
What is the correct way of resizing the image here?
I am pretty annoyed by my problem here and couldn't really find anything useful.
The problem is, I have huge images (we're talking about 4000*5000 pixels) where I detect objects and add bounding boxes as well as some thin lines. So far, so good. Now I want to accurately analyze many of those images in parallel, where the MATLAB figure window is just too slow. Thus, I want to save those images. What happens then, is that the thin lines in the MATLAB figure window become thicker making the graphics file more or less useless.
Here's the code:
img = imread('blabla.jpg');
polyfig = figure, imagesc(img);
axis off
axis image
hold on
for i=1:nl
line([xmin xmax],[lines(1,i) lines(1,i)],'Color','r', 'LineWidth', 1);
end
This results in the nice figure, where, when zooming in, the lines are very very thin as I want them to be. Now I want to save those images:
set(polyfig,'PaperUnits','centimeters','PaperPosition',[0 0 100 100])
outfile = sprintf('/folders/result_poly_%s.eps', img_name(1:end-4));
print('-deps', outfile, '-r400');
I tried tons of different options when saving, but never getting the results I want to. Here are two examples:
http://imgur.com/kRkPLNY
http://imgur.com/FCP41Hk
I really don't know where I could change something to get what I want to get. Maybe you have a hint for me? I'd greatly appreciate that!
You can capture the image from the figure with :
h = figure(1); imshow(Img);
saveas(h,'SavePath');