How to save spectrum(magnitude of stft) as RGB image and restore it exactly?

19 views (last 30 days)
san jan
san jan on 13 Jan 2021
Edited: Elady on 1 Jul 2021
I use short time fourier transform(stft), then save the magnitude of stft as RGB image, but when i read it again its different little, the code as following:
s = stft(y,Fs,'Window',wind,'OverlapLength',olen,'FFTLength',nfft);% y is 1-d signal
smag = abs(s); % get magnitude of stft
smag=rescale(smag); % rescale it between 0 to 1
mIm = im2uint8(smag);% to convert it to uint8
mImRGB=ind2rgb(mIm,jet(128)); % to convert it to colorheat which similar to spectrum displayed by matlab(not exactly)
imwrite(mImRGB,'path\smagg.png');% save it as PNG image
smag22=imread('path\smagg.png');% read it again
smag22=rgb2ind(smag22,jet(128)); % convert it back to be smilar to mIm
similarity=sum(sum(abs(smag22-mIm)));% the result its not zero mean its not magnitude(stft) is not restore exactly! the restorted spectrum is distorted the data of spectrum
any solution?

Answers (1)

Elady on 1 Jul 2021
Edited: Elady on 1 Jul 2021
There are two potential culprits that could explain the difference you see.
  1. The conversion from a linear index to an RGB colorspace
  2. The save/load using a graphical image file format.
I would start with suspect 1 (conversion to/from RGB) by bypassing the file save/load.
>> mImRGB = ind2rgb(mIm,jet(128)); % to convert it to colorheat which similar to spectrum displayed by matlab(not exactly)
>> smag22 = rgb2ind(mImRGB,jet(128)); % convert back
>> similarity=sum(sum(abs(smag22-mIm))) % what is the result now?
If the similarity is nonzero, then the problem is with the RGB mapping. Keep in mind that the rgb2ind is not a simple mapping of (RGB) -> linear index, as it can introduce spatial effects such as dithering as well quantization artifacts. It is optimized for visual data. You may eliminate some of that by using coarser colormap (e.g. jet(64)) but you will also lose dynamic range by doing so.
If you can give up the colorization process and save a monochrome image, it could potentially eliminate the issue altogether.
You may also want to inspect the difference image between mIm and smag22, and the maximum norm of that difference.
>> imagesc(mIm-smag22)
>> max(abs(smag22-mIm),[],'all')
It could be a small difference of 1 pixel shade value - and it's up to to decide whether it's significant or not.
Lastly, as a general rule, graphic image formats are not meant to be used as precise numerical storage containers, but rather optimized for visual representation. You should make sure the format you choose is not lossy (i.e introduce compression). You may save your STFT as a graphic image only for visualization purposes. For a true precise storage, I would opt to use a mat file or any other binary




Community Treasure Hunt

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

Start Hunting!

Translated by