problems with imshow() and rgb2gray() in MATLAB - matlab

Good afternoon,
when running the following code:
testImage = double(imread(testfile));
figure; imshow(testImage)
greyTestImage = rgb2gray(testImage);
figure; imshow(greyTestImage)
I get unclear and mostly blank Images, I was unable to fx it using the colormap. The following is teh original image and the two resulting figures:
1:
2:
3:

You have to know the format of the image you are trying to read. To make this sure, I always use the following piece of code in my programs when I want to convert user defined image from unknown format to uint8 grayscale :
% load image
[filename, pathname] = uigetfile({'*.*'},'image file');
fullFilename = [pathname filename];
% Get image info, read it accordingly
info = imfinfo(fullFilename);
if(strcmp('truecolor',info.ColorType))
I = imread(fullFilename);
Igray = uint8(rgb2gray(I));
clear I
elseif(strcmp('grayscale',info.ColorType))
Igray = uint8(imread(fullFilename));
elseif(strcmp('indexed',info.ColorType))
[I,map] = imread(fullFilename);
Igray = uint8(ind2gray(I,map));
clear I map
else
error('statPart:FormatImage','Image format error');
end
clear info
Also, this : testImage = double(imread(testfile)); won't work if you assume testfile is uint8 and want to convert it to double (in double intensity shall range from 0 to 1). You have to do testImage = double(imread(testfile)) / 255;
Hope this help.
Cheers

Have you tried converting to 8 bit unsigned integers?
testImage = double(imread('PEYXW.jpg'));
figure; imshow(uint8(testImage))
greyTestImage = rgb2gray(uint8(testImage));
figure; imshow(greyTestImage)

This is probably an issue with the image you are loading.
The input to the rgb2gray function needs to be a 3-channel color image (MxNx3 matrix for the R,G,B channels).
If you use a built-in Matlab sample image, you can effectively do:
imdata = imread('ngc6543a.jpg');
figure; imshow(imdata)
Then:
test = rgb2gray(imdata);

Actually, Matlab provides the function Im2double instead of double to convert images to double precison:
testImage = im2double(imread(testfile));
figure; imshow(testImage)
greyTestImage = rgb2gray(testImage);
figure; imshow(greyTestImage)
In double precision, image RGB values are between 0 and 1, for uint8 they range between 0 and 127. When you use the double function, all RGB values keep their value, but they are in double precision. This means that any RBG tiple with values >= 1 will result in a double >= 1 and thus produce a white space in your image.
im2doubleactually scales the values to the range [0 1].

Related

Interpolation algorithm all values 255 -MATLAB

I trying to create my own nearest neighbor interpolation algorithm in Matlab to enlarge an image of 556×612 to 1668×1836.
This is homework!!!
I have attempted this already but encounter the error where the values inside M gets (not all but most) transformed to 255 (White Space), and I cannot get my head around why. Any help would be appreciated! The picture is a picture of a zebra.
%Take in image and convert to greyscale
I = imread('Zebra.jpg');
Igray = rgb2gray(I);
% Step-3: Resize the image to enlarged 1668x1836 by interpolation
% Step-3(a) : Using nearest neighbour
%First we will need to work out the dimension of the image
[j , k] = size(Igray);
%Now we need to set the size of the image we want
NewX = 1836;
NewY = 1668;
% Work out ratio of old to new
ScaleX = NewX./(j-1);
ScaleY = NewY./(k-1);
%Image Buffer
M = zeros(NewX, NewY);
%Create output image
for count1 = 1:NewX
for count2 = 1:NewY
M(count1,count2) = Igray(1+round(count1./ScaleX),1+round(count2./ScaleY));
end
end
%Show Images
imshow(M);
title('Scaled Image NN');
try imshow(M,[]). You created M without specifying type, which makes it double. double images are [0-1], so imshow by default makes white everything with higher value than 1.
Alternatively, create M to be uint8 as the original image
M = zeros(NewX, NewY,'uint8');
even better code would be:
M = zeros(NewX, NewY,class(Igray));

error while masking an image

I just want to threshold it before applying algorithm.i tried it in one algorithm and got perfect result.but here i considered binary image and then masking.i just want the intervertebral disc(ellipse portion) which is in between vertebrae .can you suggest any other method?
close all;
clear all;
%%
Img = imread('Sub.png');
Img=rgb2gray(Img);%convert to single channel as data do not contain color image
Img=im2bw(Img,.16);
fig1=figure;
subplot(221)
imshow(Img); title('Original Image')
m1 = uint8(Img>35);
subplot(222), imshow(m1,[]); title('Mask m1');
m2=uint8(Img<300);
subplot(223), imshow(m2,[]); title('Mask m2');
sd = stdfilt( double(Img), ones(3,3));
m3= uint8(sd<18);
subplot(224), imshow(m3,[]); title('Mask m3');
fig2=figure;
I = uint8(Img.* m1);
I = uint8(I.* m2);
I = uint8(I.* m3);
subplot(221), imshow(I);
title('Masked Img')
i'm getting error as
I cannot view mask1 , mask 2, mask3 and also I'm getting error
Error using .*
Integers can only be combined with integers of the same class, or scalar doubles.
Error in test1 (line 22)
corrected code is
close all;
clear all;
%%
Img = imread('Sub.png');
Img=rgb2gray(Img);%convert to single channel as data do not contain color image
Img=im2bw(Img,.16);
fig1=figure;
subplot(221)
imshow(Img); title('Original Image')
m1 = uint8(Img>35);
subplot(222), imshow(m1,[]); title('Mask m1');
m2=uint8(Img<300);
subplot(223), imshow(m2,[]); title('Mask m2');
sd = stdfilt( double(Img), ones(3,3));
m3= uint8(sd<18);
subplot(224), imshow(m3,[]); title('Mask m3');
fig2=figure;
Img(~m1)=0;
Img(~m2)=0;
Img(~m3)=0;
subplot(221), imshow(Img);
title('Masked Img')
There are probably multiple issues with the code. While applying a mask using multiplication is technically possible, I recommend to use indexing instead:
Img(~mask)=0;
This code sets every pixel which is not in mask to zero.
There is probably another issue with your code. You are using uint8 to get a uint8 image, but the function does not rescale. If you input a normalized double image (values between 0 and 1) you will end up with a black image because it contains only 0 and 1 values. Use im2uint8 to convert images, but I think what you are trying to do here could be done on the double image as well.

error while drawing several x-marks on a binary image in matlab

I am trying to draw several x-marks on a binary image to some co-ordinates.
My output should look like this
To do this i have written some codes below
clear all;
% Here four co-ordinates are provided as an example. In my main code the co- ordinates will be hundred or thousands
position{1}.x = 10;
position{1}.y = 10;
position{2}.x = 20;
position{2}.y = 20;
position{3}.x = 30;
position{3}.y = 30;
position{4}.x = 40;
position{4}.y = 40;
% Read image as binary
image = imread('test34.jpg');
figure('name','Main Image'),imshow(image);
gray_image=rgb2gray(image);
level = graythresh(gray_image);
binary_image = im2bw(image,level);
% Define color of the x-marker and initializing shapes which i want to draw
red = uint8([255 0 0]);
markerInserter = vision.MarkerInserter('Shape','X-mark','BorderColor','Custom','CustomBorderColor',red);
i = 1;
% The loop will continue to the number of co-ordinates which will never be predefined in my main code
while i<=numel(position)
% Converting binary to RGB for only once.
if i == 1
rgb = repmat(binary_image, [1, 1, 3]);
else
rgb = repmat(binary_image, [1, 1, 1]);
end
% Position where x-marks will be drawn
Pts = int32([position{i}.x position{i}.y]);
% Draw x-marks
binary_image = step(markerInserter, rgb, Pts);
i = i+1;
end
figure('name','binary_image'),imshow(binary_image);
But i am getting these errors
Error using images.internal.imageDisplayValidateParams>validateCData
(line 119)
If input is logical (binary), it must be two-dimensional.
Error in images.internal.imageDisplayValidateParams (line 27)
common_args.CData = validateCData(common_args.CData,image_type);
Error in images.internal.imageDisplayParseInputs (line 78)
common_args = images.internal.imageDisplayValidateParams(common_args);
Error in imshow (line 227)
[common_args,specific_args] = ...
Error in test2 (line 39)
figure('name','binary_image'),imshow(binary_image);
I have tried some examples but they are experimented on RGB image while i need it on binary image and that's where i am getting errors.
Why i am getting these errors and what will be the solution?
Please provide explanation with proper code.
You code seems a bit complicated (to me) for what it is intended. Here is a simple example demonstrating how to draw red crosses using scatter on a binary image. As you see, the image in itself is binary and the markers are in color, so the 'net' image is no longer binary... Also, there is no need to convert your RGB image to graylevels before applying im2bw.
And don't forget to use hold on to avoid discarding the image when adding the markers!
Here is the code with comments:
clear
clc
close all
%// Read image
MyImage = imread('peppers.png');
%// Convert to binary. No need to use rgb2gray.
MyBWImage = im2bw(MyImage(:,:,2));
%// Define some x- and y positions for markers
xpositions = linspace(10,300,40);
ypositions = linspace(20,500,40);
imshow(MyBWImage)
%// IMPORTANT!!
hold on
%// Draw markers
scatter(xpositions.',ypositions.',80,'r','x')
With output:
Is this what you meant?

How to convert RGB images to grayscale in matlab without using rgb2gray

I'm currently using code:
i = imread('/usr/share/icons/matlab.png');
for k=1:1:m
for l=1:1:n
%a(k,l)=m*n;
a(k,l) = (.299*i(k,l,1))+(.587*i(k,l,2))+(.114*i(k,l,3));
end
end
imshow(a);
It shows only a white screen. Also the newly generated dimensions are n x m x 3 whereas it should be only m x n x 1.
If I use mat2gray it display the image like this
Since the image is a PNG, imread() is returning an integer image, with intensity values in the range [0 255] or equivalent, depending on the original bit depth. The conversion formula makes a a double image, which is expected to have intensities in the range [0 1]. Since all the pixel values in a are probably much greater than 1, they get clipped to 1 (white) by imshow().
The best option is to explicitly convert the image format before you start - this will take care of scaling things correctly:
i = imread('/usr/share/icons/matlab.png');
i = im2double(i);
a = .299*i(:,:,1) + .587*i(:,:,2) + .114*i(:,:,3); % no need for loops
imshow(a);
input=imread('test.jpg');
subplot(1,2,1), imshow(input), title('RGB Scale image');
[x,y,~] = size(input);
for i = 1:1:x
for j = 1:1:y
output(i,j) = 0.40*input(i,j,1) + 0.50*input(i,j,2) + 0.30*input(i,j,3);
end
end
subplot(1,2,2), imshow(output), title('Gray Scale image');

Matlab- zero padding

How to do this on matlab?
zero pad the face image with a five‐pixel
thick rim around the borders of the
image. show the resulting image.
Must be manual codes on script.
save this function as create_padded_image.m
function padded_image = create_padded_image(image, padding)
if nargin < 2
% if no padding passed - define it.
padding = 5;
end
if nargin < 1
% let's create an image if none is given
image = rand(5, 4)
end
% what are the image dimensions?
image_size = size(image);
% allocate zero array of new padded image
padded_image = zeros(2*padding + image_size(1), 2*padding + image_size(2))
% write image into the center of padded image
padded_image(padding+1:padding+image_size(1), padding+1:padding+image_size(2)) = image;
end
Then call it like this:
% read in image - assuming that your image is a grayscale image
$ image = imread(filename);
$ padded_image = create_padded_image(image)
This sounds like homework, so I will just give you a hint:
In MATLAB it is very easy to put the content of one matrix into another at precisely the correct place. Check out the help for matrix indexing and you should be able to solve it.
I realize you want to code this yourself, but for reference, you can use the PADARRAY function. Example:
I = imread('coins.png');
II = padarray(I,[5 5],0,'both');
imshow(II)
Note this works also for multidimensional matrices (RGB images for example)