How do I save a plotted image and maintain the original image size in MATLAB? - image

I'd like to show an image and plot something on it and then save it as an image with the same size as the original one. My MATLAB code is:
figH = figure('visible','off');
imshow(I);
hold on;
% plot something
saveas(figH,'1','jpg');
close(figH);
But the resulting image "1.jpg" has saved non-image areas in the plot as well as the image. How can I solve this problem?

The reason your new image is bigger than your original is because the SAVEAS function saves the entire figure window, not just the contents of the axes (which is where your image is displayed).
Your question is very similar to another SO question, so I'll first point out the two primary options encompassed by those answers:
Modify the raw image data: Your image data is stored in variable I, so you can directly modify the image pixel values in I then save the modified image data using IMWRITE. The ways you can do this are described in my answer and LiorH's answer. This option will work best for simple modifications of the image (like adding a rectangle, as that question was concerned with).
Modify how the figure is saved: You can also modify how you save the figure so that it better matches the dimensions of your original image. The ways you can do this (using the PRINT and GETFRAME functions instead of SAVEAS) are described in the answers from Azim, jacobko, and SCFrench. This option is what you would want to do if you were overlaying the image with text labels, arrows, or other more involved plot objects.
Using the second option by saving the entire figure can be tricky. Specifically, you can lose image resolution if you were plotting a big image (say 1024-by-1024 pixels) in a small window (say 700-by-700 pixels). You would have to set the figure and axes properties to accommodate. Here's an example solution:
I = imread('peppers.png'); %# Load a sample image
imshow(I); %# Display it
[r,c,d] = size(I); %# Get the image size
set(gca,'Units','normalized','Position',[0 0 1 1]); %# Modify axes size
set(gcf,'Units','pixels','Position',[200 200 c r]); %# Modify figure size
hold on;
plot(100,100,'r*'); %# Plot something over the image
f = getframe(gcf); %# Capture the current window
imwrite(f.cdata,'image2.jpg'); %# Save the frame data
The output image image2.jpg should have a red asterisk on it and should have the same dimensions as the input image.

Related

What's the easiest way to extract contour of segmented image?

Let's say i have an image like that one:
After some quick messing around, i got a binary image of the axe, like that:
What is the easiest/fastest way to get the contour of that image using GNU/Octave?
In Octave you can use bwboundaries (but I will welcome patches that implement bwtraceboundaries)
octave:1> pkg load image;
octave:2> bw = logical (imread ("http://i.stack.imgur.com/BoQPe.jpg"));
octave:3> boundaries = bwboundaries (bw);
octave:4> boundaries = cell2mat (boundaries);
octave:5> imshow (bw);
octave:6> hold on
octave:7> plot (boundaries(:,2), boundaries(:,1), '.g');
There are a couple of differences here from #Benoit_11 answer:
here we get the boundaries for all the objects in the image. bwboundaries will also accept coordinates as input argument to pick only a single object but I believe that work should be done by further processing your mask (may be due to the jpeg artifacts)
because we get boundaries for all objects, so you get a cell array with the coordinates. This is why we are using dots to plot the boundaries (the default is lines and it will be all over the image as it jumps from one object to other). Also, it is not documented whether the coordinates given are for the continuous boundary, so you should not assume it (again, why we plot dots).
the image that is read seems to have some artifacts, I will guess that is from saving in jpeg.
You can use bwtraceboundary in the Image package. Here is the Matlab implementation but that should be pretty similar using Octave:
First estimate starting pixel to look for boundary and then plot (BW is the image). (Check here )
dim = size(BW);
col = round(dim(2)/2)-90;
row = min(find(BW(:,col)));
boundary = bwtraceboundary(BW,[row, col],'N');
imshow(BW)
hold on;
plot(boundary(:,2),boundary(:,1),'g','LineWidth',3);
Output:

MATLAB: Extract point array from .tif image

I am relatively new to Matlab image processing stuff. I will be precise:
I have a .tif image which I would like to load into Matlab and subsequently extract an array of points (x,y) by simple mouse clicking. For Example:
I click three times => 3 xy coordinates => 2 dim array in workspace with three rows.
Any ideas?
Thanks.
You should look into imread for loading tif image from disk.
You will find imshow useful for displaying the image you read from disk.
Finally, you can use ginput to interactively mark locations on the displayed image.

How to display a Gray scale image using boundary defined in another binary image

I have a original gray scale image(I m using mammogram image with labels outside image).
I need to remove some objects(Labels) in that image, So i converted that grayscale image to a binary image. Then i followed the answer method provided in
How to Select Object with Largest area
Finally i extracted an Object with largest area as binary image. I want that region in gray scale for accessing and segmenting small objects within that. For example. Minor tissues in region and also should detect its edge.
**
How can i get that separated object region as grayscale image or
anyway to get the largest object region from gray scale directly
without converting to binary or any other way.?
**
(I am new to matlab. I dono whether i explained it correctly or not. If u cant get, I ll provide more detail)
If I understood you correctly, you are looking to have a gray image with only the biggest blob being highlighted.
Code
img = imread(IMAGE_FILEPATH);
BW = im2bw(img,0.2); %%// 0.2 worked to get a good area for the biggest blob
%%// Biggest blob
[L, num] = bwlabel(BW);
counts = sum(bsxfun(#eq,L(:),1:num));
[~,ind] = max(counts);
BW = (L==ind);
%%// Close the biggest blob
[L,num] = bwlabel( ~BW );
counts = sum(bsxfun(#eq,L(:),1:num));
[~,ind] = max(counts);
BW = ~(L==ind);
%%// Original image with only the biggest blob highlighted
img1 = uint8(255.*bsxfun(#times,im2double(img),BW));
%%// Display input and output images
figure,
subplot(121),imshow(img)
subplot(122),imshow(img1)
Output
If I understand your question correctly, you want to use the binary map and access the corresponding pixel intensities in those regions.
If that's the case, then it's very simple. You can use the binary map to identify the spatial co-ordinates of where you want to access the intensities in the original image. Create a blank image, then copy over these intensities over to the blank image using those spatial co-ordinates.
Here's some sample code that you can play around with.
% Assumptions:
% im - Original image
% bmap - Binary image
% Where the output image will be stored
outImg = uint8(zeros(size(im)));
% Find locations in the binary image that are white
locWhite = find(bmap == 1);
% Copy over the intensity values from these locations from
% the original image to the output image.
% The output image will only contain those pixels that were white
% in the binary image
outImg(locWhite) = im(locWhite);
% Show the original and the result side by side
figure;
subplot(1,2,1);
imshow(im); title('Original Image');
subplot(1,2,2);
imshow(outImg); title('Extracted Result');
Let me know if this is what you're looking for.
Method #2
As suggested by Rafael in his comments, you can skip using find all together and use logical statements:
outImg = img;
outImg(~bmap) = 0;
I decided to use find as it less obfuscated for a beginner, even though it is less efficient to do so. Either method will give you the correct result.
Some food for thought
The extracted region that you have in your binary image has several holes. I suspect you would want to grab the entire region without any holes. As such, I would recommend that you fill in these holes before you use the above code. The imfill function from MATLAB works nicely and it accepts binary images as input.
Check out the documentation here: http://www.mathworks.com/help/images/ref/imfill.html
As such, apply imfill on your binary image first, then go ahead and use the above code to do your extraction.

matlab divide an image according to the user input

I have an Image :
I want to manually divide the image into the parts as show below:
The division of the image should be user controlled. I should be able to take the user input of the rectangular squares in which I am trying to divide the Image.
The output is shown below :
How can I do this in matlab?
After operating on the individual images can I join them back together to make the image as one ?
Use imrect to create an interactive rectangular selection tool on top of the input image. Look closely at the second example.
Once the user has selected a rectangel, you can use imcrop to get the corresponding part.
Saving the relative position of the selected rectangle (i.e., the position vector [x y w h]) you can then "re-embbed" the part into the original image at the same location.
I finally got it . Thanks !
Img = imread('cameraman.tif');
figure();
imshow(Img);
h = imrect();
crop_area = wait(h);
cropped = imcrop(Img, crop_area);
imshow(cropped);
This works well.

Strange/Magical Image visualization with Matlab

I have an Image of double, I want to show it with unsigned int 16 bit, so I do:
I = im2uint16(I);
figure;imshow(I);title('Image being saved')
This shows this (with its normal noise):
Now I want to write this image with .png with Bit Depth 16 Bit. I do:
imwrite(I,'image.png','BitDepth',16);
And now the image, opened with Photoshop CS5, or Windows Photo Viwer looks like this: (the noise is magically disappeared):
Can someone explain this strange behaviour ?
How to Reproduce this error
Download in C:\test\ the image I used here:
Now run this script:
I = im2double(imread('C:\test\test_matlab.tif'));
% Add gaussian noise with variance = 0.0012
I = imnoise(I,'gaussian',0,0.0012);
figure,imshow(I);
imwrite(I,'C:\test\withNoise.tif');
And compare the figure in matlab versus the file saved
It's difficult to say because you didn't give enough data to reproduce, but I'd guess the problem is related to a display issue: the image is larger than you physical display window, hence some downsampling must be applied to display it. Depending on how that resampling is done, the result can be -in this scenario- very different, visually.
Suppose that matlab applies a nearest-neighbour resampling for its display, that would explain why the image looks very noisy; instead, if another image viewer applies a bilinear interpolation or something similar, that would amount to a local average that practically filters out the white noise.
To test this, try the same with a small image. Or try zooming the apparently clean image, to see it at real size (100% : one image pixel = one display pixel)
Update: See also here
Here's what I did:
%# read the image (why is it so big?)
I = im2double(imread('https://p7o1zg.bay.livefilestore.com/y1pcQVsmssygbS4BLW24_X1E09BKt_Im-2yAxXBqWesC47gpv5bdFZf962T4it1roSaJkz5ChLBS0cxzQe6JfjDNrF7x-Cc12x8/test_matlab.tif?psid=1'));
%# add noise
I = imnoise(I,'gaussian',0,0.0012);
%# write tiff
imwrite(I,'withNoise.tif');
%# read the tiff again
I2 = imread('withNoise.tif');
class(I2) %# -- oopsie, it's uint8 now!
%# convert to uint16 as in original post
I = im2uint16(I);
%# writ again
imwrite(I,'withNoise16.png','bitDepth',16);
%# read it
I2 = imread('withNoise16.png');
%# compare
all(all(I==I2)) %# everything is equal
So there is no funky stuff going on in writing/reading the image (though you lose some information in the bit conversion - your original image only takes up about a third of the dynamic range, so you'll lose more information that if you stretched the contrast before conversion).
However, the image is 2k-by-2k. When I only look at the top right corner of the image (taking 500-by-500 pix), it is displayed the same in Matlab and other graphics programs. So I bet it's a matter of resampling your image that Matlab does differently from other programs. As #leonbloy suggests, Matlab may be doing nearest-neighbor resampling, while other programs would do interpolation.

Resources