Generate same array as what imwrite produces from a double array
1 view (last 30 days)
Show older comments
I have a double array "im" of size (224,224,3) with values between -0.1472 and 1.1472. I take this array and use imwrite(im, imfilename) to generate a jpg. If I read back this jpg image file using imread I get an array of same size (224,224,3) but the values are from 0 to 255.
My question is how can I generate the same values (from 0 to 255) as what I get by doing imread on the jpg file from my original array without using the intermediate process of imwrite and imread?
0 Comments
Accepted Answer
DGM
on 9 Apr 2021
Edited: DGM
on 9 Apr 2021
I can answer that question, but I don't know that you mean to be doing the thing you're trying to do.
Most IPT tools assume that image data of class 'double' has a black value of 0 and a white value of 1. These are the values that are of importance when the data is rescaled/truncated when converting between classes. When you do your imwrite/imread routine, what's happening is that imwrite() gets fed an image of class 'double'. In order to scale the data to 'uint8', it's going to discard anything outside of [0 1] and rescale the remaining to fit [0 255]. You've truncated the data.
If this truncation is desired, then you can do it like this:
mydoublepic = rand(100)*1.2944-0.1472;
myuint8pic = im2uint8(mydoublepic); % if you have IPT
%myuint8pic = uint8(mydoublepic*255); % if you don't have IPT
If truncation is undesired, then the question becomes whether you want the output data to be 'uint8' at all, or whether you simply want it rescaled. If you want it to be 'uint8', then you'd have to scale it somehow to fit within [0 1] before casting. How exactly you do that would depend on what the image data means in context and how subsequent operations are going to expect it to be scaled/centered.
If you don't care what the output class is, you could just multiply im*255, but bear in mind that some tools wouldn't know what to do with an image of that class and data range.
3 Comments
DGM
on 9 Apr 2021
Edited: DGM
on 9 Apr 2021
What you're looking at there is simply artifacts due to the lossy compression. The small size of the image and its color properties make them particularly bad. I don't think it's documented, but the default quality setting that imwrite() uses when writing jpg is 75%, which is pretty low.
For what it's worth, setting the quality parameter higher does reduce the effect somewhat, but using a lossless setting removes it entirely, demonstrating that the effect is indeed caused by the lossy compression.
% read file
load('imageGen.mat')
% this is the unadulterated image recast as uint8
recast=im2uint8(img);
% plot error as a function of compression quality parameter
q=50:100;
jpgerr=zeros(size(q));
for n=1:numel(q)
% default is 75%
imwrite(img,'temp.jpg','quality',q(n));
imr=imread('temp.jpg');
jpgerr(n)=immse(recast,imr);
end
plot(q,jpgerr); hold on; grid on
ylabel('MSE')
% imwrite supports lossless jpg output
% this recovers the image without error
imwrite(img,'temp.jpg','mode','lossless');
imr=imread('temp.jpg');
jpglerr=immse(recast,imr);
plot(q,jpglerr*ones(size(q)))
% png output is also lossless by default
imwrite(img,'temp.png');
imr=imread('temp.png');
pngerr=immse(recast,imr);
plot(q,pngerr*ones(size(q)))
If you want to be assured that the error is just the artifacts, I wrote the image in a lossless format, opened it in GIMP, exported as JPG, 75% quality, 4:2:0 chroma subsampling, zero smoothing, and got the exact same image that imwrite() produces with its defaults. Like I said, the color content of the image really makes the compression brutal, and the extreme chroma subsampling makes it worse.
If your goal is still to replicate the compression artifacts, then you'll have to implement the compression algorithm. Matlab does have a DCT tool available (dct2()), but you'll have to split the image channels and other ancillary stuff. I'm not familiar with the details of the image format specification, so that's about all I can recommend. Someone may have an implementation on the FEX or elsewhere.
More Answers (0)
See Also
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!