Save image from imshow - matlab

I want to save the image to a file after doing imshow(im,[]); to display it later in GUI. I am trying the following code, but it doesn't work.
New= imshow(uint8(MHI{t}),[]);
imwrite(New,'TMHI.jpg','jpg')
Any help will be appreciated. Thank you.

The imshow function is only used to show the image in MATLAB. If you want to save it, you don't need the imshow at all. And: the value (New) returned by imshow() is the handle to the figure. You need that handle if you want to modify how the figure is shown on the screen.
To write the image to the disk, you only need the imwrite function, which has the syntax:
imwrite(A,filename)
where A is the image array.
If the file name ends with .jpg, then MATLAB will create a JPEG image by default, so you don't need to specify that. (But of course, you still can.)
But before saving: you have a problem with the normalization of the image. MATLAB assumes that a double image is scaled to [0,1] and that a uint8 image is scaled to [0,255]. With imshow(im,[]) you override these defaults and make MATLAB calculate new values. You will experience the same problem when saving. The solution is to normalize the image properly. This can be done using the im2uint8 function, which scales the input to a maximum value of 255, and converts it to uint8. Note that you'll have to remove the minimal value manually, if that is needed:
newImage = im2uint8(MHI{t} - min(MHI{t}(:)));
imwrite(newImage,'TMHI.jpg')

In case you really need to save the contents of the displayed figure in matlab (sometimes also useful when you use imagesc for display as it has some smart logic for properly scaling your value ranges) you might be interested in the savefig and saveas which lets you save the contents of a figure. Its also possible to save graphs or figures with subfigures like that.
In that case, you would use something like:
F = imshow(uint8(MHI{t}),[]);
saveas('MHI.png');
In case you really just need to save the image stored in MHI{t}, hbaderts 's answer is the way to go...

Just use my NormalizeImage function and save the image normaly:
img = NormalizeImage(imgDouble);
imwrite(img ,'MyImage.png');
My NormalizeImage function:
function img8bpp = NormalizeImage(imgDouble)
minImgDouble = min(imgDouble(:));
factor = (255-0)/(max(imgDouble(:)) - minImgDouble);
%img8bppB = im2uint8(imgDouble-minImgDouble);
img8bpp = uint8((imgDouble-minImgDouble).*factor);
%im2uint8 does not work, duno y
%imgDif = img8bppB - img8bpp;
end

Related

How do I save images with face detection bounding box using the Batch Image Processor app in Matlab

I'm a newbie to Matlab and I'm trying to perform face detection on a batch of images. I'm using this simple face detection code which works with the Image Processing Toolbox and the Computer Vision Toolbox. I'm using the Batch Image Processor App and wrote my code as a function that I apply to a batch of images. What I need as an outcome are the four values of each bounding box (this works), and I want to save each image with the bounding box drawn, in order to check if the face is detected correctly (which doesn't work). This is the function:
function results = facedetection(im)
FDetect = vision.CascadeObjectDetector('FrontalFaceLBP','MergeThreshold', 5);
BBface = step(FDetect,im);
figure,
imbb = imshow(im); hold on
for i = 1:size(BBface,1)
rectangle('Position',BBface(i,:),'LineWidth',2,'LineStyle','-
','EdgeColor','r');
end
hold off;
imwrite(imbb,'test.jpg'); %this is the line that doesn't work
results.face=BBface; %this gives me the values of each bounding box
end
When I apply this function it provides me with the values of the bounding box, and in the imshow it shows the image with the bounding box around the face. However, the imwrite function doesn't work and gives the following error:
Error using imwrite (line 420) Expected DATA to be one of these types:
numeric, logical
Instead its type was matlab.graphics.primitive.Image.
Error in facedetection (line 13) imwrite(imbb,'test.jpg');
Does anyone know how to solve this issue? Is it possible to save all images with the bounding box using the Batch Image Processor app and if so, how? Is it also possible to save the images without using imshow? I don't have to see the results directly, as long as I can save them.
I'm sorry if this question is too vague, but I hope someone can help me a bit further.
EDIT: I found out that the Batch Image Processor can be used to save the images, as long as the image is put into a results. string in the function (see documentation), but I don't know how to do this. I changed my code as followed:
function results = facedetection(im)
FDetect = vision.CascadeObjectDetector('FrontalFaceLBP','MergeThreshold', 5);
BBface = step(FDetect,im);
figure,
imbb = imshow(im); hold on
for i = 1:size(BBface,1)
rectangle('Position',BBface(i,:),'LineWidth',2,'LineStyle','-
','EdgeColor','r');
end
hold off;
BBimage = imfuse (im, BBface); %this doesn't work
results.BBValues=BBface;
results.BBimage=BBimage;
end
This code returns a complete green hued image (?!). So probably something goes wrong in the imfuse part. How do I put the im and the drawn rectangle together in the BBimage?
I solved the problem using the insertShape function. The complete function becomes as follows:
function results = facedetection(im)
FDetect = vision.CascadeObjectDetector('FrontalFaceLBP','MergeThreshold', 3);
BBvalues = step(FDetect,im);
hold on
for i = 1:size(BBvalues,1)
BBimage = insertShape (im,'rectangle',BBvalues(i,:),'Color','yellow');
end
hold off;
results.Values3=BBvalues;
results.Image3=BBimage;
end
When this function is applied to a batch of images in the Batch Image Processor app, the 'export results of all processed images to files'-button allows you to save the images including the bounding box rectangle. It saves each image with its original filename and an additional '_Image3'.
I'm using this code now to test the most effective threshold, which is why I named them Values3 and Image3 refering to the threshold 3. It works fine!
This means that imbb that you are trying to write out to a file is not the proper type to write out to a file.
Can you try something like this after your for loop and see what happens?
frame = getframe(figure);
image = frame2im(frame);
imwrite(image, 'test.jpg');
Eventually, you want to move your imwrite inside your for loop so you can batch process it.
You would declare a file name before the for loop like :
basename = 'MyFileName-';
Then inside the for loop, you would do something like
filename = [basename, num2str(i)];
imwrite(image, filename);

insert text into image without computer vision system toolbox - Matlab

In the Matlab central (http://www.mathworks.com/matlabcentral/answers/26033-how-to-insert-text-into-image) I found this code:
Text = sprintf('Create text inserter object \nwith same property values');
H = vision.TextInserter(Text);
H.Color = [1.0 1.0 0];
H.FontSize = 20;
H.Location = [25 25];
I = im2double((imread('football.jpg')));
InsertedImage = step(H, I);
imshow(InsertedImage);
How can I do the same without using the computer vision system toolbox?
Thanks
To follow up on my comment:
A = imread('football.jpg');
YourText = sprintf('Create text inserter object \nwith same property values');
figure;
imshow(A);
hText = text(25,25,YourText,'Color',[1 1 0],'FontSize',20);
Giving the following:
Look at the doc page to see all the options available to modify/customize your text. Notice that you don't have to use sprintf to generate the string, however the newline character (\n) must be used inside sprintf in order to work.
EDIT In response to your comment below, if you need to save the image with text embedded in it you can use getframe to get the content of the figure and then imwrite to save it:
hFrame = getframe(gca) %// Get content of figure
imwrite(hFrame.cdata,'MyImage.tif','tif') %// Save the actual data, contained in the cdata property of hFrame
EDIT #2 As alternatives to using getframe, look here as there are 2 nice ideas proposed, i.e. using saveas or avi files.
The answer above (Benoit_11) requires that you display the image first, write the text, then save the image. This becomes very slow if you are processing the frames of a video (not a single image, or a few of them). To get a much faster processing time, you have to write directly to the image matrix. One alternative I can think of (but that is not very elegant) is to create (or download) small templates for the alphabet characters (e.g. 20x20), then overwrite the image matrix in the required region with those templates. For example, for an RGB "true color" image, we'll have something like this:
im(y:y+19,x:x+19,:)=template;

pixel values changing after doing imwrite in MATLAB

The imwrite function is behaving in a weird way. I have modified a single pixel value of an image. After performing imwrite, however, the pixel value is either getting changed to a entirely new value OR is remaining unchanged.
function imwriteCheck(input_image,output_image)
a=imread(input_image);
fprintf('\nBefore modification a(1,1,1)=%d\n',a(1,1,1));
a(1,1,1)=50;
fprintf('\nAfter modification a(1,1,1)=%d\n',a(1,1,1));
imwrite(a,output_image);
b=imread(output_image);
fprintf('\nValue at b(1,1,1)=%d\n',b(1,1,1));
end
I've tested this function with two images and the outputs are as follows:
>> imwriteCheck('MOM.jpg','MOMout.jpg')
Before modification a(1,1,1)=206
After modification a(1,1,1)=50
Value at b(1,1,1)=170
>> imwriteCheck('durga.jpg','durgaout.jpg')
Before modification a(1,1,1)=63
After modification a(1,1,1)=50
Value at b(1,1,1)=63
I cannot understand why this is happening. Thank you for your help.
if you write to a jpg file, pixel values get changed because of their lossy compression technique. you can write to a jpg file using lossless mode but then you wont be able to view the image anywhere else.
try writing to a bmp or png file, you'll see the pixel values are NOT changing.

Matlab imwrite() quality

I'm very new to Matlab, though I know a few other programming languages, so please forgive me if this is something simple. I have not been able to find any answers to this, either on StackOverflow or elsewhere.
I produce a figure using the following code:
figure(6),imageplot(P); drawnow;
Which looks like this:
I then save this image to my computer using the following commands:
imwrite(P, 'images/plot.png');
And the resulting image is tiny, and missing some of the color information:
If, however, I utilize the save function in the open figure (image #1) and save it manually, I get exactly what I want, which is that exact image stored on my computer.
How would I program that? I assumed that imwrite() would just write the image directly, but apparently I'm doing something wrong. Any advice? Perhaps it has something to do with the imageplot command? I cannot seem to get that to work in imwrite.
Update: Based on the comments below, I have begun using "imresize" with the "nearest" option. This scales the image properly, but the resulting image is still curiously darker (and therefore has less information) than if I hit the "save" button in the figure.
Image saved from figure:
Image using "imresize" with "nearest" option:
The MATLAB imwrite command saves exactly the number of pixels as specified in your image matrix. This is the actual result of your computation; the reason the output is "tiny" is because it is supposed to be. To make it larger, would be to simply scale/zoom it as required.
The save figure option however does something quite different: it rasterizes the the output you obtain in the figure window and gives you the option for saving it as an image. This is evident in the fact that when you do so, you obtain a white background in addition to your result which is really just the grey background you see before you save it; this can be adjusted by resizing the figure window before utilizing the save option.
If you're looking to simply make the output figure larger, I would recommend using something along the lines of the imresize command.
Say, if you want the default size to be twice the size of the real result, simply use:
imresize(P, 2.0);
For more options, try help imresize.
The command you need for the "Save As..." functionality of figures is called "print". I often use
print(gcf, '-dpng', 'some_filename.png')
or
print(gcf, '-depsc', 'some_filename.eps','-r0')
to save a figure as it is shown on screen. The format png offers a small filesize and excellent quality, and it is understood by most image viewers and browsers. The eps format is a vector format, which I use for printig. The '-r0' option specifies "use the same size as given by the screen resolution" for the vector format properties.

Saving contents of figure to a matrix in Matlab ( whithout using getframe, nor with saving to file)

The function getframe captures whatever is visible on the screen. However in my application I want the figure to be invisible when storing its content in a matrix. So what the getframe does is that, for a short period, it makes the figure visible and captures its contents and then sets the 'visibile' property back to what it was before screen capture.
I do not want that flash happening on the screen. As well, saving in file and reading it back reduces speed. There has got to be a way to get around this.
hFig=figure('Visible','off'')
text ('String','ABC','fontsize',300)
imageData = getframe(hFig);
img = imageData.cdata; % img is what I am interested in
The only way I know to do this is to print the figure to a temporary file. For example:
%Create a figure
hFig=figure('Visible','off')
text ('String','ABC','fontsize',300)
%Save the figure to a tiff file using a salted name
tmpName = sprintf('Temp_Figure_%04d.tiff', floor(rand*1000));
print(['-f' num2str(hFig)], '-dtiff', tmpName)
%Read the data
img = imread(tmpName);
%Delete the temporary figure
delete(tmpName);
Not the prettiest thing, but it seems to work.