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.
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:
But my programs are all in MATLAB.
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:
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).
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
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).
Related
I have data that change in size and want to display them in the same window. The command
void ImageResize( BasicImage im, Number num_dim, Number... )
seems like a potential fit, but the syntax is not clear at all.
Let's say I have 512x5 data set and now it needs to be 367x5.
The , Number...) indicates that this command takes a different number of parameters, all of them interpreted as number parameters. Commands which do this, usually use one of their other parameters to specify how many such parameters follow.
A typical example for this is also the SliceN command.
In this particular case, the command not only allows you to change the size of the dimensions in the image, but also the number of dimensions. It is a very useful command to f.e. change a 2D image into a 3D stack or the like.
The command ImageResize( BasicImage im, Number num_dim, Number... ) does several things:
It replaces im in-place, so the meta-data, display and window remains the same
It adjusts the dimension calibration when the dimension size is changed. Here, the assumption is, that the field-of-view before and
after the resize is the same. (The command can be used to easily scale
images as shown in the example below.)
All values of the image im are set to zero. ( If you need to keep the values, you need to act on an image clone!)
Example 1: Resizing image with bilinar interpolation
image before := GetFrontImage()
number sx, sy
before.GetSize(sx,sy)
number factor = 1.3
image after := before.ImageClone()
after.ImageResize( 2, factor*sx, factor*sy ) // Adjusts the empty container with meta-data
after = warp(before, icol/factor, irow/factor ) // interpolate data
after.ShowImage()
Example 2: Extend 2D image into 3D stack
number sx = 100
number sy = 100
image img := RealImage("2D",4,sx,sy)
img = iradius* Random()
img.ShowImage()
OKDialog("Now into a stack...")
number sz = 10
img.ImageResize(3,sx,sy,sz) // All values are zero now!
img = iradius * Random()
I am working on a project where i have to first normalize the image i.e convert the pixel range of my image from 16-235 (as it is only luminance component of the image , pixel values are always defined in the range 16-235) to 0 - 1 then i perform dwt and idwt on the image after the processing i want to again maps these pixels values from 0 - 1 to 16 - 235. ie if the pixel value is 1 value then it should be stored in the image matrix as 235.
for which i tried the following matlab code ,this code works perfectly fine when i denormalize the image immediately after normalization , but output becomes complete white if i use this code after performing dwt and idwt.
for j = 1:1:361
for k=1:1:361 %dimensions of my matrix
if(distorted1(j,k)~=0)
temp=distorted1(j,k);
temp1=temp/0.0045;
distorted1(j,k)=int8(temp1)+1;
end
end
end
imshow(distorted1);
it seems like the result of your idwt is of type double ( or single ) and not int anymore. convert to uint8 and then imshow it.
Trying to imshow an image of type double/single will saturate all pixels with values larger than 1.0 (rather than 255 for images of type int).
% Clean up the BlackAndWhiteCheckerBoard.bmp by making it a true
% bi-color image where
% ColorOne >=128
% ColorTwo <128
% If the
% Input: ColorOne, ColorTwo, BlackAndWhiteCheckerBoard.bmp
% Output: CleanCheckerBoard, CleanCheckerBoard.bmp <-- not a typo!
Here is what the checkboard image looks like:
I'm really unsure what to do. Help would be much appreciated!
That can be done very easily with Boolean operations. First read in the image, then use Boolean operations to set your pixels accordingly. Following the steps of your question definition, and assuming that you set your working directory in MATLAB to be where you have placed the image, do the following:
ColorOne = ...; %// You define here
ColorTwo = ...; %// You define here
im = imread('BlackAndWhiteCheckerBoard.bmp'); %// Read in the image
CleanCheckerBoard = im; % // Copy input to output
%// Set colours according to spec
CleanCheckerBoard(im >= 128) = ColorOne;
CleanCheckerBoard(im < 128) = ColorTwo;
%// Save your image
imwrite(CleanCheckerBoard, 'CleanCheckerBoard.bmp');
The question is poorly worded, but my assumption is that any intensities that are >= 128, you wish to set to ColorOne and those intensities that are < 128 you set to ColorTwo. If I have interpreted this incorrectly, please leave me a comment and I will adjust my code accordingly.
The above code will read in your image, and you must specify what ColorOne and ColorTwo are. After, I make a copy of this image to the output variable that is part of the spec, and then I use Boolean operations to do what I just mentioned in the previous paragraph. After, I take this new image and save this to a file called CleanCheckerBoard.bmp as specified in the spec.
I am trying to overlay an activation map over a baseline vasculature image but I keep getting the same error below:
X and Y must have the same size and class or Y must be a scalar double.
I resized each to 400x400 so I thought it would work but no dice. Is there something I am missing? It is fairly straight forward for a GUI I am working on. Any help would be appreciated.
a=imread ('Vasculature.tif');
b = imresize (a, [400,400]);
c=imread ('activation.tif');
d= imresize (c, [400,400]);
e=imadd (b,d);
Could it be the bit depth or dpi?
I think one of your images is RGB (size(...,3)==3) and the other is grayscale (size(...,3)==1). Say the vasculature image a is grayscale and the activation image c is RGB. To convert a to RGB to match c, use ind2rgb, then add.
aRGB = ind2rgb(a,gray(256)); % assuming uint8
Alternatively, you could do aRGB = repmat(a,[1 1 3]);.
Or to put the activation image into grayscale:
cGray = rgb2gray(c);
Also, according to the documentation for imadd the two images must be:
nonsparse numeric arrays with the same size and class
To get the uint8 and uint16 images to match use the im2uint8 or im2uint16 functions to convert. Alternatively, just rescale and cast (e.g. b_uint8 = uint8(double(b)*255/65535);).
Note that in some versions of MATLAB there is a bug with displaying 16-bit images. The fix depends on whether the image is RGB or gray scale, and the platform (Windows vs. Linux). If you run into problems displaying 16-bit images, use imshow, which has the fix, or use the following code for integer data type images following image or imagesc:
function fixint16disp(img)
if any(strcmp(class(img),{'int16','uint16'}))
if size(img,3)==1,
colormap(gray(65535)); end
if ispc,
set(gcf,'Renderer','zbuffer'); end
end
chappjc's answers is just fine, I want to add a more general answer to the question how to solve the error message
X and Y must have the same size and class or Y must be a scalar double
General solving strategy
At which line does the error occur
Try to understand the error message
a. "... must have the same size ...":
Check the sizes of the input.
Try to understand the meaning of your code for the given (type of) input parameters. Is the error message reasonable?
What do you want to achieve?
Useful command: size A: returns the size of A
b. "... must have the same class ...":
Check the data types of the input arguments.
Which common data type is reasonable?
Convert it to the chosen data type.
Usefull command: whos A: returns all the meta information of A, i.e. size, data type, ...
Implement the solution: your favorite search engine and the matlab documentation are your best friend.
Be happy: you solved your problem and learned something new.
A simple code :
a=imread ('image1.jpg');
b=imresize (a, [400,400]);
subplot(3,1,1), imshow(b), title('image 1');
c=imread ('image2.jpg');
d= imresize (c, [400,400]);
subplot(3,1,2), imshow(d), title('image 2');
[x1, y1] = size(b) %height and wedth of 1st image
[x2, y2] = size(d) %height and wedth of 2nd image
for i = 1: x1
for j = 1: y1
im3(i, j)= b(i, j)+d(i, j);
end
end
subplot(3,1,3), imshow (im3), title('Resultant Image');
I have a floating point data [size: 4000 X 140 ]. I want to convert it to an IplImage in OpenCV. To have an idea about data, I am giving first 8 X 8 entries of that data.These data are very close to zero. So, I am getting a dark image.
-1.14E-04 -4.71E-04 -1.27E-04 2.43E-04 4.58E-04 1.63E-04 2.56E-04 2.86E-04
1.12E-04 -2.80E-04 2.89E-05 -2.18E-04 4.08E-05 -2.23E-04 -7.96E-05 -3.97E-05
-3.98E-04 -2.35E-04 6.11E-04 4.53E-05 4.74E-05 8.02E-05 2.10E-04 1.10E-04
2.08E-04 3.09E-04 -1.34E-04 -2.58E-04 -2.25E-04 -1.74E-04 2.28E-04 2.65E-04
-6.65E-04 -2.94E-04 6.37E-04 -5.16E-05 9.90E-05 1.05E-04 -2.20E-04 -5.49E-05
1.85E-04 5.69E-04 -5.19E-04 -4.98E-05 2.07E-04 -2.00E-05 1.24E-04 1.49E-04
1.54E-04 -4.09E-04 4.29E-04 -7.67E-04 5.19E-04 3.56E-04 -4.82E-04 3.66E-04
-1.71E-04 -5.15E-04 5.71E-04 -5.68E-04 -2.75E-04 -6.17E-05 1.40E-04 2.19E-04
1) when I am multiplying these entries with a factor like 10E4 or 10E5, I can see an image. But image quality is very poor unlike matlab-generated image.
[
MATLAB code corresponding image:
[path,file] = uigetfile;
data = load(strcat(file,path));
figure;
imagesc(data);
colormap(gray);
]
[
OpenCV code sequence:
I created CvMat and filled it with those data.
I prepared IplImage from that CvMat.
I resized the image( 560 X 420 )
]
2) There are many negative data. Should those be consider zero? or Should all the data be added with a number(like 10E-4) to make all entries positive? or should I proceed through someother ways?
3) I changed contrast , brightness. But those seem to be useless.
Try mapping the minimum value to 0.0 and the maximum to 1.0.