Generate same array as what imwrite produces from a double array

2 vues (au cours des 30 derniers jours)
Omkar Karve
Omkar Karve le 8 Avr 2021
Commenté : Omkar Karve le 11 Avr 2021
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?

Réponse acceptée

DGM
DGM le 9 Avr 2021
Modifié(e) : DGM le 9 Avr 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 commentaires
DGM
DGM le 9 Avr 2021
Modifié(e) : DGM le 9 Avr 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.
Omkar Karve
Omkar Karve le 11 Avr 2021
Perfectly clear. Thanks!!.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Get Started with Image Processing Toolbox dans Help Center et File Exchange

Produits


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by