1

I have a image.mat of about 4MB. The size of some image file can also be 4MB. Can the image.mat be transferred to image file?

I tried this, but that doesn't do the trick:

load image.mat      %load Iw
imshow(mat2gray(Iw))
imwrite(Iw,'image.png');
IwNew = imread('image.png');
isequal(Iw,IwNew)

The result is 0; am I misunderstanding something?

The number in Iw are very important, so Iw can not be changed.

process flowchart

Actually my real problem is how to store float numbers into an image?

But MATLAB does not support Tiff 6.0, so I'll have to find some workaround. I am doing a blind watermarking,and the decimal fraction of a number in Iw is important because it involve the information about another image.So the Iw can not be changed.

Actually,Mathematica can store floating floating-point data: enter image description here But my programs are all in MATLAB.

partida
  • 501
  • 4
  • 20
  • It's impossible... What I usually do is save in eps format and then convert the eps into png. It keeps the image pretty much the same. – 16per9 May 03 '16 at 08:56
  • related: http://www.stackoverflow.com/questions/14003402/writing-an-image-with-floating-point-values – Rody Oldenhuis May 03 '16 at 09:05
  • What version of MATLAB are you using? Because TIFF and HDF seem obvious candidates for your case. But as stated, you're going to lose some information (what does a pixel value of `-realmax` mean?)...What data type is `Iw`, and what is its range? You might be able to come up with a map that is able to preserve all information... – Rody Oldenhuis May 03 '16 at 09:11
  • @RodyOldenhuis I am using Matlab.The class of `Iw` is double. It ranges from 0 to 255 or so. – partida May 03 '16 at 10:51
  • OK, but what *version* of MATLAB? There is a world of difference between MATLAB R2006 and MATLAB R2016a – Rody Oldenhuis May 03 '16 at 11:01
  • @RodyOldenhuis R2015b – partida May 03 '16 at 11:02

2 Answers2

1

According to Matlab documentation:

"If A is a grayscale or RGB color image of data type double or single, then imwrite assumes that the dynamic range is [0,1] and automatically scales the data by 255 before writing it to the file as 8-bit values."

In other words: imwrite performs automatic conversion from double to uint8. if you wish to keep the values of Iw unchanged, save it as a mat file and not as an image.

If you do want to save it as an image - there is going to be some loss of information. In this case, there are two things which need to be done:

  1. Change the dynamic range of the matrix to [0,1]. (in your case, the range is between -0.0035 to 255.0035. Also, the matrix contain inf values).

  2. If you want to get an equality, scale IwNew by 255, and convert it to uint8.

Code:

load image.mat      %load Iw

%step 1, change the dynamic range of the image to [0,1]. 
%One way to do it is by using mat2gray on each channel separately.
Iw(:,:,1) = mat2gray(Iw(:,:,1));
Iw(:,:,2) = mat2gray(Iw(:,:,2));
Iw(:,:,3) = mat2gray(Iw(:,:,3));

%write the image to file
imwrite(Iw,'image.png');

%read the image
IwNew=imread('image.png');

%scale it, and convert to uint 8
Iw2 = uint8(Iw*255);

%check equality
isequal(Iw2,IwNew) 

Result:

ans =

 1

Alternatively, if you want to convert IwNew to double, perform the following:

%conversion to double
Iw2 = double(IwNew)/255;

Notice that in this case, the matrices won't be equal to one another, Due to the loss of information which happened during the imwrite process (conversion from double to uint8). Instead, they will be epsilon-close to one another, where epsilon = 0.0001.

In order to test this, write the following:

%equality check
sum(abs(Iw2(:)-Iw(:))>0.0001)   

Result:

ans =

 0
ibezito
  • 5,782
  • 2
  • 22
  • 46
  • I don't want to change Iw and I expect the class of IwNew is double instead of uint8 – partida May 03 '16 at 06:25
  • but Iw(:,:,1) = mat2gray(Iw(:,:,1)) actually changed Iw. – partida May 03 '16 at 07:04
  • Read my answer carefully. It is impossible to save Iw as an image without losing information. Firstly, due to the fact that Iw is not a valid image (it contains values greater than 255 and smaller than 0), Secondly, due to the fact that imwrite function saves double images as uint8. – ibezito May 03 '16 at 07:19
0

My MATLAB (R2010a) with the image processing toolbox is perfectly capable of storing double-valued pixel values, and retrieve them without loss of data.

Here's a shameless copy of this answer:

% Some random, data of type double
A = 7.6*rand(10);

% Construct TIFF image...
t = Tiff('test.tif', 'w'); 

% ...with these custom parameters...
tagstruct = struct(...
    'ImageLength'        , size(A,1),...
    'ImageWidth'         , size(A,2),...
    'Compression'        , Tiff.Compression.None,...
    'SampleFormat'       , Tiff.SampleFormat.IEEEFP,...  % floating point
    'Photometric'        , Tiff.Photometric.MinIsBlack,...
    'BitsPerSample'      , 64,... % 8 bytes / double
    'SamplesPerPixel'    , 1,...
    'PlanarConfiguration', Tiff.PlanarConfiguration.Chunky);

t.setTag(tagstruct); 

% ...and write it to disk.
t.write(A); 
t.close();


% Read the data actually written, and check if all 
% information was indeed preserved:
B = imread('test.tif');
isequal(A,B)

Result:

ans =
     1

Adjust in obvious ways if you have more than 1 channel (RGB).

Community
  • 1
  • 1
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96