This question already has answers here:
Turn a MATLAB plot into image
(2 answers)
Save a plot in Matlab as a matrix [duplicate]
(2 answers)
How can I save an altered image in MATLAB?
(8 answers)
How do I save a plotted image and maintain the original image size in MATLAB?
(1 answer)
Closed 5 years ago.
Suppose you have one image.
You plot this image.
After that, you plot a green tracing on top of that image.
You make this plot easily using the plot function.
After this initial plot, you add a second tracing on top of the same image.
Therefore you have a figure with two plots just like in this image.
How can I store the result of this multiple plots to one variable without saving to file and then reading the final result?
I can do this if I print and then read the image but I want the same result without having the additional step of saving to file.
Any clue?
Example code and figure:
imshow(a)
hold on
plot(centroidsFiltered(:,2),centroidsFiltered(:,1),'.g','LineWidth',0.5)
plot(int32(centroidsFiltered(i,2)), int32(centroidsFiltered(i,1)), '.g', 'MarkerSize',20)
The data resulting from the plot is this figure.
How can I store all the resulting information to one variable?
Data can be downloaded here: https://expirebox.com/download/c95e9a0e5ac5530729f6960679ec9733.html
CLARIFICATION
What I want as an output variable from this plot is the original image matrix, with the update in the matrix positions where the green line and the green marker is perceptible.
You could try using getframe. See Documentation
imshow(a)
hold on
plot(centroidsFiltered(:,2),centroidsFiltered(:,1),'.g','LineWidth',0.5)
plot(int32(centroidsFiltered(i,2)), int32(centroidsFiltered(i,1)), '.g', 'MarkerSize',20)
b = getframe(gca);
To recreate the plot:
figure;
imshow(b.cdata)
Note: That the size of b.cdata and a will not be exactly the same. Since this is a screen grab of the axis b will most likely have some extra pixels around the border. However, with a careful setting of units to pixels and using the optional rect input to getframe you may be able to get the output dimensions correct.
Related
This question already has an answer here:
What does the index refer to when selecting a pixel on an image in Matlab?
(1 answer)
Closed 6 years ago.
I have gray scale image "lena.bmp". I want read this image in matlab using imread() function.
When i use code below to read and show image my image is dark (black).
img = imread('lena.bmp');
imshow(img);
But when i use code below, I have no problem to view.
[img map]= imread('lena.bmp');
imshow(img,map);
It seems that my first code doses not reading image in grayscale mode (like what rgb2gray function generate).
My image is as follows:
What can i do to solve this problem?
Your image is an "indexed" image. That means it contains integer values which act as "labels" more than anything, and each of those labels is mapped to a colour (i.e. an rgb triplet). Your map variable represents that mapping; at row 5 you have the rgb triplet that corresponds to 'label' "5", for instance.
To see what I mean, do unique(img) and you'll see that the values of your img array are in fact quite regular. The command rgbplot can demonstrate the actual colourmap graphically. Run rgbplot(map) on your map variable to see the mapping for each of the red green and blue colours.
Now, save and read the image below on your computer as img2 and compare the array values.
This image was generated by converting from the "indexed" image you linked to, to a "grayscale" one using photoediting software (the GIMP). The difference is that
in a grayscale image, the pixel values represent actual intensities, rather than integer 'labels'. Imread reads grayscale images as uint8 images by default, meaning it assigns intensity values to pixels ranging from 0 (black) to 255 (white). Since these values happen to be integers you could still cheat and treat them as 'labels' and force a colour-mapping on them. But if you assign a 'linear map' (i.e. value 1 = intensity 1, value 2 = intensity 2, etc) then your image will look as you would expect.
You'll see that the values from unique(img2) are quite different. If you imshow(img2) you'll see this displays as you'd expect. If you don't specify a colormap for imshow, it will assume that the map is a linear mapping from the lowest to the highest value in the image array, which explains why your indexed image looked weird, since its values were never supposed to correspond to intensities.
Also try imagesc(img2) which will show this but using the "current" colormap. imagesc causes the colormap to be "scaled", so that the lowest colour goes to the lowest value in the image, and similarly for the highest.
The default colormap is jet so you should see a psychedelic looking image but you should be able to make out lena clearly. If you try colormap gray you should see the gray version again. Also try colormap hot. Now to make sense of the colormaps, try the rgbplot command on them (e.g. rgbplot(gray), rgbplot(hot) etc).
So, going back to imshow, imshow basically allows you to display an indexed image, and specify what colormap you want to use to display it. If you don't specify the colormap, it will just use a linear interpolation from the lowest value to the highest as your map. Therefore imshow(img) will show the image pretty much in the same way as imagesc(img) with a gray colormap. And since the values in your first img represent evenly spaced 'labels' rather than actual intensities, you'll get a rubbish picture out.
EDIT: If you want to convert your indexed image to a grayscale image, matlab provides the ind2gray function, e.g.:
[img, map] = imread('lena.bmp');
img_gray = ind2gray(img, map);
This is probably what you need if you mean to process pixel values as intensities.
This question already has answers here:
3D scatter plot with 4D data
(2 answers)
Closed 7 years ago.
I have a an nx4 matrix where each row is an observation.
The three three columsn represent by variables, and the fourth a 'fitness' parameter.
I would like to show this in a 3D scatter plot, where each axis is one of my variables and then color each point depending on how close to one of the extremes in my fourth column it is.
For example, say fitness ranged between 0 and 1. I would want observations with fintess 0 to be blue, those with fitness 1 to be red and those in-between some corresponding shade.
Any advice on how best to do this?
Thanks!
The function scatter3 has a color input argument. But you need to define the size of the markers also.
% Generate example data,
X=rand(10,1)*10;
Y=rand(10,1)*3;
Z=rand(10,1)*5;
fit=rand(10,1)*3+10;
scatter3(X,Y,Z,ones(size(X))*40,fit,'fill')
Use scatter3 with an appropriate colormap:
scatter3(data(:,1), data(:,2), data(:,3), 10, data(:,4), '*')
colormap(hsv)
colorbar
where
data is your matrix
10 is markersize
'*' is the marker shape
hsv is the selected colormap
I am struggling to find a good contour detection function that would count the number of contour in bw images that I have processed using some previous tools. As you can see, my profile picture is an example of such images,
,
In this image, ideally, I wish to have a function which counts four closed contour.
I don't mind if it also detects the really tiny contours in between, or the entire shape itself as extra contours. As long as it counts the medium sized ones, I can fix the rest by applying area threshold. My problem is that any function I have tried detects only one contour - the entire shape, as it cannot separate it to the su-conours which are connected to one another.
Any suggestions?
Here is my shot at this, although your question might get closed because it's off-topic, too broad or a possible duplicate. Anyhow I propose another way to count the number of contours. You could also do it using bwboundaries as was demonstrated in the link provided by #knedlsepp in the possible duplicate. Just for the sake of it here is another way.
The idea is to apply a morphological closure of your image and actually count the number of enclosed surfaces instead instead of contours. That might end up being the same thing but I think it's easier to visualize surfaces.
Since the shapes in your image look like circle (kind of...) the structuring element used to close the image is a disk. The size (here 5) is up to you but for the image you provided its fine. After that, use regionprops to locate image regions (here the blobs) and count them, which comes back to counting contours I guess. You can provide the Area parameter to filter out shapes based on their area. Here I ask the function to provide centroids to plot them.
Whole code:
clear
clc
close all
%// Read, threshold and clean up the image
Im = im2bw(imread('ImContour.png'));
Im = imclearborder(Im);
%// Apply disk structuring element to morphologically close the image.
%// Play around with the size to alter the output.
se = strel('disk',5);
Im_closed = imclose(Im,se);
%// Find centroids of circle-ish shapes. Youcan also get the area to filter
%// out those you don't want.
S = regionprops(~Im_closed,'Centroid','Area');
%// remove the outer border of the image (1st output of regioprops).
S(1) = [];
%// Make array with centroids and show them.
Centro = vertcat(S.Centroid);
imshow(Im)
hold on
scatter(Centro(:,1),Centro(:,2),40,'filled')
And the output:
So as you see the algorithm detected 5 regions, but try playing a bit with the parameters and you will see which ones to change to get the desired output of 4.
Have fun!
I have searched the internet for a solution to the question above but have had no luck up to now. I have been producing a number of 2D plots where the origin of (0,0 point) is represented by an image. I have made these by plotting the data on an image, where the image is all white apart from the desired symbol at the center point (so I can reshape it as needed). I then move the axis so they cross at the center point. This all works fine, but I now have to create a number of plots using ‘fill’ to place two shaded areas on the plot that overlap in the center. This causes the symbol to be difficult to see even using ‘alpha’.
I therefore have two options to get the desired effect, both requiring me to put an image on top of the figure after the data is plotted. These options are:
1) I place the image on top of the plot and apply alpha to it (May not look very good as it will mute the plot).
2) The better option would be to crop the image around the symbol and then position it on top of the plot so the image center is at the origin (I have no idea how to position the image this way).
Both methods need the image to be placed on top of the plot after the data is plotted. I have tried 'hold on' and calling 'figure(imagesc(Image))' neither work. I have Matlab 2012b but no toolboxes (so cannot use subimage etc.)
Thanks for any help you can give
You can set the transparency of individual pixels of an image using the 'AlphaData' option. So, you can plot the overlay as follows:
% plot your data normally
...
hold on
% assuming the overlay is a 11x11 image
image(-5:5,-5:5,image_matrix,'AlphaData',alpha_matrix);
image_matrix would obviously be the matrix with your image data stored in it, while alpha_matrix would be a matrix of the same size as image_matrix. Every pixel you want to show would have a value of 1, every pixel you want to hide (the white pixels) would be 0.
This question already has answers here:
Turning y axis upside down in MATLAB
(5 answers)
Closed 9 years ago.
Example data:
I can change the values from up to down by the command
B(end:-1:1,:)
I run it and get
However, I want to change the values on the y-axis such that they go from 0 to 180.
How can you change the values on the y-axis in Matlab?
To change direction of y axis, including axis labels and plotted values, you use
set(gca,'YDir','reverse')
When you plot an image, for example using imagesc, the YDir property is automatically set to reverse. So, to change it, set it to normal:
set(gca,'YDir','normal')