I have a little mess with a GUI developed on Matlab. Basically, I have two axes, one to plot a bitmap I want to keep all the time and another one to do some ordinary plots. My problem is that when I try to do any plot on the second axes, the image on the first one disappears and the axis get restarted. I tried to plot over the image and it remains on the figure (only shifts because the axis change once the previous image is gone).
Any idea aout what is happening? By the way, it is for a chromatic tuner that plots a degradation from green to red depending on the accuracy and the FFT of the received signal.
1) Here is the code for the image plot:
colormap(cmap);
imagesc(bmp,'Parent',handles.axes_tuner);
hold(handles.axes_tuner,'on');
% Vertical line in front of the image
plot([L/2,L/2],[-length(bmp(:,1)),2*length(bmp(:,1))],'b','LineWidth',1.5);
axis(handles.axes_tuner,'off');
hold(handles.axes_tuner,'off');
2) Plot on the other axes
cla(handles.axes_fft);
hold(handles.axes_fft,'on');
plot(f,spectrum,'b-','Parent',handles.axes_fft);
xlabel(handles.axes_fft,'Frequency','FontSize',8);
axis([0 Fs -50 0]);
ylabel(handles.axes_fft,'Normalized Amplitude','FontSize',8);
hold(handles.axes_fft,'off');
Related
This is supposed to be very simple I think but I can't get it right...
I plot several graphical objects in a figure and now I want a bitmap of the figure, that maintains the position on the objects and the dimensions of the figure.
To give a very simple example, if I plot 2 points in coordinates (0,0) and (200,200) I expect the rendering to output a matrix of size (200,200) where pixels (0,0) and (200,200) have a gray level of 255 and the rest of the pixels are zeroed (this is in case of a 8-bit per pixel grayscale though 3I prefer a color bitmap that will reflect the colors of the objects as appear in the original figure)
Thanks
To answer my own question, this is what I did to render a figure with graphical objects to a bitmap in memory and keep it in scale: I used getFrame and then resized the result to the size of the axes. Here goes:
% plot stuff on the current axes, then...
set(gca, 'ydir', 'reverse');
xLim = get(gca, 'XLim');
yLim = get(gca, 'YLim');
rendered = getframe(gca);
imageMat = imresize(rendered.cdata, [floor(yLim(2)), floor(xLim(2))]);
Here the image is sampled twice which is both inefficient in terms of processing time and gives a somewhat degraded image. For my purposes it's ok but still a single-sample solution would be nice...
This question is regarding SIFT features and its use in MATLAB. I have some data containing the following information:
The x,y co-ordinates of each feature point
The scale at each feature point
The orientation at each feature point
The descriptor vector for each feature point. Each vector has 128 components.
I'm having a problem with drawing the keypoints onto the corresponding input image. Does anyone have an idea of how to do this? Are there any built-in functions I can use?
Thanks a lot.
If you just want to display the points themselves, read in the x and y co-ordinates into separate arrays, then display the image, use the hold on command, then plot the points. This will overlay your points on top of the image.
Assuming you have these co-ordinates already available and stored as x and y, and assuming you have your image available and stored as im, you can do this:
imshow(im);
hold on;
plot(x, y, 'b.');
Keep in mind that the x co-ordinates are horizontal and increase from the left to right. The y co-ordinates are vertical and increase from top to bottom. The origin of the co-ordinates is at the top left corner, and is at (1,1).
However, if you want to display the detection window, the size of it and the orientation of the descriptor, then suggest you take a look at the VLFeat library as it has a nice function to do that for you.
Suggestion by Rafael Monteiro (See comment below)
You can also modify each point so that it reflects the scale that it was detected at. If you want to do it this way, assume you have saved the scales as another array called scales. After, try doing the following:
imshow(im);
hold on;
for i = 1 : length(x)
plot(x(i), y(i), 'b.', 'MarkerSize', 10*scales(i));
end
The constant factor of 10 is pretty arbitrary. I'm not sure how many scales you have used to detect the keypoints and so if the scale is at 1.0, then this would display the keypoint at the default size when plotting. Play around with the number until you get results that you're comfortable with. However, if scale doesn't matter for you, the first method is fine.
Is there any way of labeling plots with images. For example, when I use the following:
plot(Y(:,1),Y(:,2),'o','LineWidth',2);
gname(names)
I can label each dot in a plot with a name. Is there any way to insert images instead of names?
It is possible, but not as convenient as gname by far. You can use the low-level version of image to insert images in your plot at arbitrary positions. Here's a simple example which puts the "Mandrill" image that comes with Matlab with its upper left corner pixel at the position (pi/2, 0):
% example plot
x = linspace(0, 2*pi, 100);
plot(x, cos(x))
% insert image
load mandrill
colormap(map)
image('CData', X, 'XData', [pi/2, pi/2 + 0.5], 'YData', [0, -0.3])
The result looks like this:
Problems with this approach:
There is no interactive point-and-click facility, you have to explicitly insert and position the image labels programmatically, or program such a point-and-click facility yourself. ginput might help doing so.
A figure window can only have one associated color map. That means if you have different images, they either all have to use the same colormap or have to be truecolor images.
Not just the position, but also the display size of the image has to be specified in the call to image, and both are by default specified with respect to the plot's coordinate system. This makes it hard to achieve the correct aspect ratio. You can switch (temporarily) to absolute units using the axes property 'Units' , but then you have to figure out the correct position in e.g. absolute millimeters or inches. Moreover, images are usually indexed with vertical coordinates increasing from top to bottom, while plots usually have vertical coordinates increasing from bottom to top. This is the reason for the negative value -0.3 in the 'YData' property above.
Alternatively, you can insert images each in their own little axes sitting on top of the plot's axes, which makes it easy to get the right orientation and aspect ratio using axis image. You'll still have the problem though to figure out the correct position for the axes.
Is it possible to display an image in multiple subplot axes, such that the image appears at the desired scale?
subplot(3,3,[1 4 7]);
%# image scaled down to fit 1 set of axes
imshow(img);
subplot(3,3,2);
plot(relevantData);
%# And so on with 5 other plots
I want to have the image scaled to either a fixed size or to fit the axes available to it, rather than to the size of a single axes.
My use case is to show a video alongside plots derived from the video, such that the plots are progressively drawn in step with the video. Once the display is correct I can save each image and combine them into a video.
Clarification
I am asking if it is possible to produce a figure as described without specifying the position of every element in absolute terms. Though one can make arbitrary figures that way (and in fact I have done so for this project), it is very tedious.
Edit:
For changing the size of the subplot:
In help subplot they mention that you can set parameters on the selected "axes" (that's what they call a plotting area in Matlab).
Using that, you can set the 'position', as seen in help axes. This property takes takes as argument:
[left, bottom, width, height]
As pointed out by #reve_etrange, one should use absolute positioning for axes 'Position'and 'OuterPosition' parameters. they can be in normalized coordinates, though.
For changing the size of the image in the subplot:
I think there are 2 useful things for you in the help imshow output:
'InitialMagnification': setting the magnification of the image.
'Parent': determines which parent imshow will use to put the image in (never tried using imshow with subplots).
I want to crop an image from a specific row onwards. Please help me how can I do this. I am a beginner in Matlab.
This page has a lot of great info on dealing with images in matlab.
When you load an image in matlab, it is loaded as a MxNx3 matrix. The third dimension stores the RGB values of each pixel. So to crop an image you simply select just the range of rows and columns you want to keep:
cropped_image = image(RowStart:RowEnd,ColStart:ColEnd,:);
See this: http://www.mathworks.com/help/techdoc/creating_plots/f9-47085.html
There is a graph editor icon in the screen where you see your graph, it should look like this:
Press it, you will get a big graph editor, now try pressing on the graph or one of the functions, in the lower right part you can set ranges, this will crop the image.
You can use imcrop function in Matlab
CropIm = imcrop(I, rectangle);
rectangle is a four-element position vector [xmin ymin width height] which indicates the size and position of the crop rectangle.
Im = imread('test.tif');
Im2 = imcrop(Im,[75 68 130 112]);
imshow(Im), figure, imshow(Im2)