I am trying to save spectrograms to jpg in python to use in machine learning. I have been able to save the spectrograms as tiff files and recreate the audio from those tiff files at a quality I am happy with. But I need to convert the 32bit floating point tiff files to jpg and I have been unable to find a method that preserves the contrast of the original tiff image.
I have tried numerous ways of converting the tiff to jpg or saving the array directly as a jpg and none of them have resulted in the contrast matching the tiff image. Every example I have found, whether using PIL or OpenCV etc, always results in an image with significantly lowered contrast. I can open the tiff file in MS paint and save it as a jpg and it looks exactly how I would like it to, the contrast is the same with maybe slightly lower quality but good enough. These 2 images came from the code below, the 'tiff' jpg was converted to jpg using ms paint and the other jpg was exported using the code below.
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=216, hop_length=1024, fmax=10000)
from PIL import Image
im =Image.fromarray(S).convert('F')
im.show()
im.save(f"sp{frame_id}.tiff")
na = np.array(S)
norm = cv2.normalize(na, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
cv2.imwrite(f'sp{frame_id}.jpg', (norm*255).astype(np.uint8))
Here is the original Tiff file https://drive.google.com/file/d/1MCtoWfGSQsxSUfsHpZi6teLH6EkqkPxP/view?usp=sharing
Tiff image saved as jpg from MS paint:

Jpg saved by opencv

As @MarkRansom suggests, there is probably some sort of non-linear signal compression going on, but I don't know enough about audio (RIAA curves?, mu-law companding? or librosa?) to tell you what.
I can offer some code that tries to give you a better contrast in your signal though. It applies a traditional gamma correction from image processing and it discards data samples lying outside 3 standard deviations from the mean - see Wikipedia 68-95-99.7 rule.
It is not definitive, so you should try to better understand what has happened to your signal and see if you can tweak/improve it:
To increase the contrast, you would need to either decrease
Nin the code so you retain only data nearer the mean and discard more outliers. Or you could increase thegammaparameter when calling theapplyGamma()function.Conversely, increasing
Nor decreasinggammawill decrease the contrast.