Plotted image is clear but saved image is blurry- why?

3 views (last 30 days)
I'm using the 99 line topology optimization code (found here -click the link "top.m").
When I run the following code in a separate script file (calling the top.m function)
top(30,10,0.5,3.0,1.5)
Lines 35-36 of this top.m function (shown below) plot the generated image (also shown below):
% PLOT DENSITIES
colormap(gray); imagesc(-x); axis equal; axis tight; axis off;pause(1e-6);
In order to save the generated image (not the plot), I modify the first line of the top.m function by adding "x=" (this returns the pixel data):
function x=top(nelx,nely,volfrac,penal,rmin);
Then, in a separate script file, I run the following code:
x_result=top(30,10,0.5,3.0,1.5)
image=-x_result; % invert the image
% because the values are less than 0 if you save it and read it again you'll see the image corrupted
% so need to scale it to be between 0 to 1
image=(image-min(image,[],'all'))/(max(image,[],'all')-min(image,[],'all'));
%resize image so doesn't look so tiny
image=imresize(image,10);
folder_name='C:\Users\User\Documents\MATLAB\project\test'
name='saved_image'
imwrite(image,fullfile(folder_name,[name '.jpg']));
And, this is the resulting 'saved_image' that I find in my folder:
Why does it look like this (blurry) and not like the plotted image? I've tried saving the plot instead but then this saves the image with a bunch of white space around it (like the image shown below). Mainly, I just want to know why they come out so different - and how do I know which is the "correct" or "accurate" image to save?

Answers (2)

DGM
DGM on 28 Jun 2022
Edited: DGM on 28 Jun 2022
If you want to retain the crisp edges of the original low-resolution image, you cannot use a continuous interpolant. The default for imresize() is 'bicubic'. Specify 'nearest' in the call to imresize(). You'll get a larger version of the image with the same blocky appearance. Obviously, the scaling factor should be an integer.
Consider the example:
A = imread('cameraman.tif');
A = imcrop(A,[104 49 32 31]);
imshow(A) % low-resolution image
% enlarge that tiny image by a factor of 6
Abicubic = imresize(A,6,'bicubic');
Anearest = imresize(A,6,'nearest');
montage({Abicubic Anearest})
Jonas is also right; don't use JPG for anything, especially not for technical purposes, and especially not in MATLAB.
  2 Comments
DGM
DGM on 29 Jun 2022
Edited: DGM on 29 Jun 2022
The first image is 32x33 (the low resolution original)
Both of the other images are 192x198. Both of the latter images have the same resolution; the only difference is the method of interpolation.
The differences between JPG and PNG are not major contributors to the effect you're seeing, but MATLAB uses relatively low quality (70% iirc) defaults and an unchangeable 4:2:0 chroma subsampling when saving JPG images. For any technical needs where:
  • accuracy matters
  • the image may need to be post-processed or published
  • edges and small features need to be preserved
using JPG will be counterproductive. It's just a general advice to avoid it unless you're prepared to live with the potential shortcomings.

Sign in to comment.


Jonas
Jonas on 28 Jun 2022
Edited: Jonas on 28 Jun 2022
use png instead of jpg, then no compression is applied and the quality will stay good
there ate several methods whichbaffect the output apprarance, e.g. the Quality parameter
set Mode do lossless to make sure that no compression is applied. note that a Quality of 100 also does according to the documentation not mean that no compression is applied
  3 Comments
Jonas
Jonas on 29 Jun 2022
there is a name value pair for 'Mode' in imwrite. add 'Mode','lossless' to your call to imwrite
more details in the documentation!
doc imwrite

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!