I have a uint8 matrix
A = (1:512,1:512,1:3)
which contains information about an 512x512 RGB image. I Also have a matrix B which is in the format of
B = (1:512,1:512)
which holds complex numbers. Now I would like to plot every complex number
B(x,y)
on the complex plane with RGB color of
A(x,y,1:3)
How can I achieve that?
1) Make your color matrix of the size Mx3 (where M is the total number of your points):
A=reshape (A,512*512,3);
2) Use Scatter plot:
scatter(real(B(:)), imag(B(:)), [], A/255)
Note that here your colormap should be from 0 to 1. Assuming that your original A contained the values from 0 to 255, you need to divide by the maximum value.
for r=1:512
for c=1:512
plot( B(r,c) ,'Color',reshape(A(r,c,1:3),1,3),'LineStyle','none','Marker','o')
end
end
I couldnt figure out how to make the reshape work in vectorized form without an error. This works though (albeit very slowly)!
I need to take a very large matrix that is generated by using the function imread(). This turns an image (mine is a jpg file; 691x763) into a matrix.
I need to divide each element in the matrix by 255 and show each element with at least 3 decimal places.
What I've tried:
output_precision(4) but it didn't work for the elements inside the matrix.
format long e but the values inside the matrix were still unaffected.
You should use im2double http://octave.sourceforge.net/image/function/im2double.html which does the scaling to 0..1 for you independently of the input format which might be uint, uint16, int16 and so on.
I'm guessing imread() gave you a matrix of uint8. Try this instead:
I = imread('image.jpg'); %// your image
A = double(I)/255; %//convert matrix to double before dividing it by 255
Why we convert gray levels into double before using numeric operations on image in matlab?
Is it necessary to do so ?
Because integer types like uint8 have saturated arithmetic in MATLAB, plus floating-point types have more precision when doing certain operations.
Also it is safer to upcast say a uint8 to double than it is to downcast in the other direction.
Just to give an example, say you wanted to change the dynamic range of an image by raising it to a power of 2:
img = imread('peppers.png');
subplot(121), imshow(im2double(img).^2), title('double')
subplot(122), imshow(img.^2), title('uint8')
You can see how the uint8 image got saturated with most values at 255.
Even more, using fraction exponents will throw an error for integer types:
>> img.^(1.1);
Error using .^
Integers can only be raised to positive integral powers.
I have an RGB image m in MATLAB
I normalized it using the formula
im = mean(m,3);
im = (im-min(im(:))) / (max(im(:))-min(im(:)));
I read that the normalized module stretches the image pixel values to cover the entire pixel value range (0-1) but I still have some steps between 0 and 1 in the histogram of my normalized image.
Can anyone help me out here by explaining the reason of these grey values.
Thank You
I assume you use the mean of the three components instead of the function rgb2gray because it has some advantages in your case. (rgb2gray does something similar: it uses a weighted sum).
Subtracting the minimum and dividing by the maximum doesn't convert your image to binary. It will only scale all values to the range (0,1), which is the case in your example. This only means that all values are between 0 and 1, not exactly 0 or 1. If you want a binary image, i.e. only 0 and 1, you will need to use a threshold to convert the grayscale image to binary.
A method which is often used, is to calculate a threshold using Otsu's method:
threshold = graythresh(im); % calculate threshold
binaryImage = im2bw(im,threshold); % convert image to binary
If your image is saved as uint8 then normalizing the image should convert your image to binary, as uint8 only can handle integer numbers and any numbers between are rounded. That means you assume the optimal threshold to be at 0.5.
a process of mine produces 256 binary (logical) matrices, one for each level of a grayscale source image.
Here is the code :
so = imread('bio_sd.bmp');
co = rgb2gray(so);
for l = 1:256
bw = (co == l); % Binary image from level l of original image
be = ordfilt2(bw, 1, ones(3, 3)); % Convolution filter
bl(int16(l)) = {bwlabel(be, 8)}; % Component labelling
end
I obtain a cell array of 256 binary images. Such a binary image contains 1s if the source-image pixel at that location has the same level as the index of the binary image.
ie. the binary image bl{12} contains 1s where the source image has pixels with the level 12.
I'd like to create new image by combining the 256 binary matrices back to a grayscale image.
But i'm very new to Matlab and i wonder if someone can help me to code it :)
ps : i'm using matlab R2010a student edition.
this whole answer only applies to the original form of the question.
Lets assume you can get all your binary matrices together into a big n-by-m-by-256 matrix binaryimage(x,y,greyvalue). Then you can calculate your final image as
newimage=sum(bsxfun(#times,binaryimage,reshape(0:255,1,1,[])),3)
The magic here is done by bsxfun, which multiplies the 3D (n x m x 256) binaryimage with the 1 x 1 x 256 vector containing the grey values 0...255. This produces a 3D image where for fixed x and y, the vector (y,x,:) contains many zeros and (for the one grey value G where the binary image contained a 1) it contains the value G. So now you only need to sum over this third dimension to get a n x m image.
Update
To test that this works correctly, lets go the other way first:
fullimage=floor(rand(100,200)*256);
figure;imshow(fullimage,[0 255]);
is a random greyscale image. You can calculate the 256 binary matrices like this:
binaryimage=false([size(fullimage) 256]);
for i=1:size(fullimage,1)
for j=1:size(fullimage,2)
binaryimage(i,j,fullimage(i,j)+1)=true;
end
end
We can now apply the solution I gave above
newimage=sum(bsxfun(#times,binaryimage,reshape(0:255,1,1,[])),3);
and verify that I returns the original image:
all(newimage(:)==fullimage(:))
which gives 1 (true) :-).
Update 2
You now mention that your binary images are in a cell array, I assume binimg{1:256}, with each cell containing an n x m binary array. If you can it probably makes sense to change the code that produces this data to create the 3D binary array I use above - cells are mostly usefull if different cells contain data of different types, shapes or sizes.
If there are good reasons to stick with a cell array, you can convert it to a 3D array using
binaryimage = reshape(cell2mat(reshape(binimg,1,256)),n,m,256);
with n and m as used above. The inner reshape is not necessary if you already have size(binimg)==[1 256]. So to sum it up, you need to use your cell array binimg to calculate the 3D matrix binaryimage, which you can then use to calculate the newimage that you are interested in using the code at the very beginning of my answer.
Hope this helps...
What your code does...
I thought it may be best to first go through what the code you posted is actually doing, since there are a couple of inconsistencies. I'll go through each line in your loop:
bw = (co == l);
This simply creates a binary matrix bw with ones where your grayscale image co has a pixel intensity equal to the loop value l. I notice that you loop from 1 to 256, and this strikes me as odd. Typically, images loaded into MATLAB will be an unsigned 8-bit integer type, meaning that the grayscale values will span the range 0 to 255. In such a case, the last binary matrix bw that you compute when l = 256 will always contain all zeroes. Also, you don't do any processing for pixels with a grayscale level of 0. From your subsequent processing, I'm guessing you purposefully want to ignore grayscale values of 0, in which case you probably only need to loop from 1 to 255.
be = ordfilt2(bw, 1, ones(3, 3));
What you are essentially doing here with ORDFILT2 is performing a binary erosion operation. Any values of 1 in bw that have a 0 as one of their 8 neighbors will be set to 0, causing islands of ones to erode (i.e. shrink in size). Small islands of ones will disappear, leaving only the larger clusters of contiguous pixels with the same grayscale level.
bl(int16(l)) = {bwlabel(be, 8)};
Here's where you may be having some misunderstandings. Firstly, the matrices in bl are not logical matrices. In your example, the function BWLABEL will find clusters of 8-connected ones. The first cluster found will have its elements labeled as 1 in the output image, the second cluster found will have its elements labeled as 2, etc. The matrices will therefore contain positive integer values, with 0 representing the background.
Secondly, are you going to use these labeled clusters for anything? There may be further processing you do for which you need to identify separate clusters at a given grayscale intensity level, but with regard to creating a grayscale image from the elements in bl, the specific label value is unnecessary. You only need to identify zero versus non-zero values, so if you aren't using bl for anything else I would suggest that you just save the individual values of be in a cell array and use them to recreate a grayscale image.
Now, onto the answer...
A very simple solution is to concatenate your cell array of images into a 3-D matrix using the function CAT, then use the function MAX to find the indices where the non-zero values occur along the third dimension (which corresponds to the grayscale value from the original image). For a given pixel, if there is no non-zero value found along the third dimension (i.e. it is all zeroes) then we can assume the pixel value should be 0. However, the index for that pixel returned by MAX will default to 1, so you have to use the maximum value as a logical index to set the pixel to 0:
[maxValue,grayImage] = max(cat(3,bl{:}),[],3);
grayImage(~maxValue) = 0;
Note that for the purposes of displaying or saving the image you may want to change the type of the resulting image grayImage to an unsigned 8-bit integer type, like so:
grayImage = uint8(grayImage);
The simplest solution would be to iterate through each of your logical matrices in turn, multiply it by its corresponding weight, and accumulate into an output matrix which will represent your final image.