Creating a binary image - matlab

clear all;
clc;
imag = imread('286502.png');
image_binary = im2bw(imag,0.85); %converte image to binary
image_binary = not(image_binary);
figure(1);clf
imagesc(image_binary);colormap(gray)
I am using this code to genarate a binary image of an ellipse having its inside as white while outside as black.But , the problem i am facing is that whenever the foreground and background of my input ellipse is either light or dark then the binary image becomes all black or all white.

if you want to keep the gray-scale nature of our image, you may remove the line im2bw command because that flattens the gray-scale values into binary (0-1 or white/black).
if you just want to show a binary image in gray color, you can try customizing the colormap
colormap([0 0 0;0.5 0.5 0.5]);

im2bw(imag,0.85) thresholds at a fixed value, which will work for some images but not for others. I recommend that you binarize with a method such as Otsu, which determines an optimal threshold for each image individually.
image_binary = imbinarize(imag);

Related

How to create an inverse gray scale?

I have an image with dark blue spots on a black background. I want to convert this to inverse gray scale. By inverse, I mean, I want the black ground to be white.
When I convert it to gray scale, it makes everything look black and it makes it very hard to differentiate.
Is there a way to do an inverse gray scale where the black background takes the lighter shades?
Or, another preferable option is to represent the blue as white and the black as black.
I am using img = rgb2gray(img); in MATLAB for now.
From mathworks site:
IM2 = imcomplement(IM)
Is there a way to do an inverse gray scale where the black
background takes the lighter shades?
Based on your image description I created an image sample.png:
img1 = imread('sample.png'); % Read rgb image from graphics file.
imshow(img1); % Display image.
Then, I used the imcomplement function to obtain the complement of the original image (as suggested in this answer).
img2 = imcomplement(img1); % Complement image.
imshow(img2); % Display image.
This is the result:
Or, another preferable option is to represent the blue as white and
the black as black.
In this case, the simplest option is to work with the blue channel. Now, depending on your needs, there are two approaches you can use:
Approach 1: Convert the blue channel to a binary image (B&W)
This comment suggests using the logical operation img(:,:,3) > 0, which will return a binary array of the blue channel, where every non-zero valued pixel will be mapped to 1 (white), and the rest of pixels will have a value of 0 (black).
While this approach is simple and valid, binary images have the big disadvantage of loosing intensity information. This can alter the perceptual properties of your image. Have a look at the code:
img3 = img1(:, :, 3) > 0; % Convert blue channel to binary image.
imshow(img3); % Display image.
This is the result:
Notice that the round shaped spots in the original image have become octagon shaped in the binary image, due to the loss of intensity information.
Approach 2: Convert the blue channel to grayscale image
A better approach is to use a grayscale image, because the intensity information is preserved.
The imshow function offers the imshow(I,[low high]) overload, which adjusts the color axis scaling of the grayscale image through the DisplayRange parameter.
One very cool feature of this overload, is that we can let imshow do the work for us.
From the documentation:
If you specify an empty matrix ([]), imshow uses [min(I(:)) max(I(:))]. In other words, use the minimum value in I as black, and the maximum value as white.
Have a look at the code:
img4 = img1(:, :, 3); % Extract blue channel.
imshow(img4, []); % Display image.
This is the result:
Notice that the round shape of the spots is preserved exactly as in the original image.

Creating intensity band across image border using matlab

I have this image (8 bit, pseudo-colored, gray-scale):
And I want to create an intensity band of a specific measure around it's border.
I tried erosion and other mathematical operations, including filtering to achieve the desired band but the actual image intensity changes as soon as I use erosion to cut part of the border.
My code so far looks like:
clear all
clc
x=imread('8-BIT COPY OF EGFP001.tif');
imshow(x);
y = imerode(x,strel('disk',2));
y1=imerode(y,strel('disk',7));
z=y-y1;
figure
z(z<30)=0
imshow(z)
The main problem I am encountering using this is that it somewhat changes the intensity of the original images as follows:
So my question is, how do I create such a band across image border without changing any other attribute of the original image?
Going with what beaker was talking about and what you would like done, I would personally convert your image into binary where false represents the background and true represents the foreground. When you're done, you then erode this image using a good structuring element that preserves the roundness of the contours of your objects (disk in your example).
The output of this would be the interior of the large object that is in the image. What you can do is use this mask and set these locations in the image to black so that you can preserve the outer band. As such, try doing something like this:
%// Read in image (directly from StackOverflow) and pseudo-colour the image
[im,map] = imread('http://i.stack.imgur.com/OxFwB.png');
out = ind2rgb(im, map);
%// Threshold the grayscale version
im_b = im > 10;
%// Create structuring element that removes border
se = strel('disk',7);
%// Erode thresholded image to get final mask
erode_b = imerode(im_b, se);
%// Duplicate mask in 3D
mask_3D = cat(3, erode_b, erode_b, erode_b);
%// Find indices that are true and black out result
final = out;
final(mask_3D) = 0;
figure;
imshow(final);
Let's go through the code slowly. The first two lines take your PNG image, which contains a grayscale image and a colour map and we read both of these into MATLAB. Next, we use ind2rgb to convert the image into its pseudo-coloured version. Once we do this, we use the grayscale image and threshold the image so that we capture all of the object pixels. I threshold the image with a value of 10 to escape some quantization noise that is seen in the image. This binary image is what we will operate on to determine those pixels we want to set to 0 to get the outer border.
Next, we declare a structuring element that is a disk of a radius of 7, then erode the mask. Once I'm done, I duplicate this mask in 3D so that it has the same number of channels as the pseudo-coloured image, then use the locations of the mask to set the values that are internal to the object to 0. The result would be the original image, but having the outer contours of all of the objects remain.
The result I get is:

MATLAB: Combine Two Grayscale Images With Different Alpha

I started writing a program in MATLAB to overlay two grayscale images of same size with different alpha dynamically. Therefore both images are plotted in one figure and beneath them is a slider with which the alpha of the second image can be increased from zero to one. So when moving the slider one can actually sees the two images blending. Suppose the slider is at 0.3 then the 'AlphaData' of the second image is set to 0.3, while the 'AlphaData' of the first image is always 1. On the screen I now see an image, which is a combination of these two images.
Now I want to get exactly this image from the figure (with the same size, as the images before) and work with it. But I have no idea how to do it.
Grayscale image is just array of numbers. Depending on how you get the data it could be 0~1 or 1~255. Overlaying two images is merely adding the numbers. Blending two images is merely computing their weighted sum.
clear;clc;close all
I1_rgb = imread('peppers.png');
I1_gray = rgb2gray(I1_rgb);
figure(1)
imshow(I1_gray)
I2_gray = imread('coins.png');
I2_gray = padarray(I2_gray, size(I1_gray)-size(I2_gray), ...
'circular', 'post');
figure(2)
imshow(I2_gray)
alpha = .3; % this can be dynamically adjusted by a slider
O1 = I1_gray + I2_gray*alpha; % overlay
figure(3)
imshow(O1)
O2 = I1_gray*(1-alpha) + I2_gray*alpha; % blend
figure(4)
imshow(O2)
For mixing colored images, see my answer at MATLAB: Applying transparent mask over an RGB image and blending with another

imshow() displays a white image for a grey image

I have computed an image with values between 0 and 255. When I use imageview(), the image is correctly displayed, in grey levels, but when I want to save this image or display it with imshow, I have a white image, or sometimes some black pixels here and there:
Whereas with imageview():
Can some one help me?
I think that you should use imshow(uint8(image)); on the image before displaying it.
Matlab expects images of type double to be in the 0..1 range and images that are uint8 in the 0..255 range. You can convert the range yourself (but change values in the process), do an explicit cast (and potentially loose precision) or instruct Matlab to use the minimum and maximum value found in the image matrix as the white and black value to scale to when visualising.
See the following example with an uint8 image present in Matlab:
im = imread('moon.tif');
figure; imshow(im);
figure; imshow(double(im));
figure; imshow(double(im), []);
figure; imshow(im2double(im));

Display transparent image on axes (MATLAB)

So I have this transparent image (http://imgur.com/fyqslAx) that I want to display on an axes in MATLAB with its transperancy. To do this, I used the code below, which works with other transparent png images that I have:
[A, map, alpha] = imread('fyqslAx.png');
h = imshow(A, map)
set(h, 'AlphaData', alpha);
This code however, does not seem to work with the image above. Im guessing this is because it has something to do with the image being grayscale and having a bitdepth of 1, resulting in the map and alpha having nothing in it (whereas the other png transparent images I have, have something in map and alpha). If I just use this:
A = imread('fyqslAx.png');
h = imshow(A)
A black background appears where the image should be transparent.
How do I display this http://imgur.com/fyqslAx with its transperancy on an axes?
EDIT: horchler's method worked; Thanks!!
If you run imfinfo('fyqslAx.png'), you'll see that the 'Transparency' is specified as 'simple' and the 'SimpleTransparencyData' is set to 0 (false). I can't find documentation on this, but I think that this may indicate that the alpha channel has been compressed into the image data because the the image is binary and grayscale. Effectively the image is a binary mask, either transparent or not. You can display your image like this:
A = imread('fyqslAx.png');
h = imshow(A);
set(h, 'AlphaData', A);
If you try to return a colormap and/or alpha channel from imread using extra output arguments, you'll see that both are empty.