Matlab Bug -- Matrix Elements Keep Maxing Out - matlab

There's a peculiar bug in my code that I can't seem to figure out. For context, I is an image, a matrix, consisting of scaled values from 0 to 255. GetSpatAvg is a function that is not included here. The problem I'm facing is that the elements in ngtdm always max out at 255. When this function finishes, I get the matrix ngtdm back consisting of many many values that are 255. The code is below exactly as it shows on my computer.
function ngtdm = getNGTDM(I,d)
[rowI, colI] = size(I);
ngtdm = zeros(256, 1);
for r=1+d:rowI-d
for c=1+d:colI-d
term = I(r,c)-getSpatAvg(r,c);
ngtdm(I(r,c)+1)=ngtdm(I(r,c)+1)+term;
end
end
end
I isolated a specific value in I, 254, in the code below.
function ngtdm = getNGTDM(I,d)
[rowI, colI] = size(I);
ngtdm = zeros(256, 1);
for r=1+d:rowI-d
for c=1+d:colI-d
if(I(r,c)==254)
term = I(r,c)-getSpatAvg(r,c);
disp(term);
ngtdm(I(r,c)+1)=ngtdm(I(r,c)+1)+term;
end
end
end
end
The variable 'term', in this instance was always 222. There were 369 instances of 222. Therefore the value at ngtdm(255) (254+1=255) should be larger than 255, yet the element still maxed out at 255. When I replace term with 222 as shown below:
ngtdm(I(r,c)+1)=ngtdm(I(r,c)+1)+222;
I get the correct value, a number larger than 255.
I can't seem to figure out why my element is always maxing out at 255. Could it be something to do with the fact that the values of I are scaled between 0 and 255. I'm pretty positive that getSpatAvg is not the issue because the correct value is being returned.
Thank You

It's not a bug - it sounds like you are using a uint8 datatype. If you convert to a datatype with more bits - e.g. uint16, uint32, single, double, etc - you will not run into this problem. I guess you are working with images, as images read using imread are read in as uint8 by default to save memory. Quickest fix: use I=double(I); either at the start of your function, or on the variable I before you put it into the functions.

Related

how to check if pixel value is increased from 255 in matlab while increasing the brightness of the image?

i am writing the code of matlab in which i just read the image and then i add + 50 on each pixel of the image it works fine and along with it i want to check the pixel value with if statment if pixel value exceed to 255 then this pixel value set to 255. but the if statment not working
here is my code
m1 = imread('owl.pgm');
m2 = imread('mecca06.pgm');
for i=1: size(m1,1)
for j=1: size(m1,2)
m1(i,j) = m1(i,j)+270;
if m1(i,j)>=255
m1(i,j)= 255;
end
end
end
figure
imshow(m1)
In MATLAB, integer addition is saturated. That means that, if m1 is uint8 (as it usually is returned from imread), then m1+50 will never be more than 255, if the sum would surpass that value, it would be set to 255 instead.
So, MATLAB automatically does what you wanted to accomplish, you don't need anything special for that.
The code in your post can be replaced by:
m1 = imread('owl.pgm');
m2 = imread('mecca06.pgm');
m1 = m1 + 270;
figure
imshow(m1)
You don't need to loop over all pixels, you can use the image as a matrix and simply do something like:
m1 = imread('owl.pgm');
m1 = min(255,m1+50);
Edit:
Depending on what datatype im1 has you may need to convert it first to something that can handle the operation you want to do, e.g. an 8-Bit integer allows only numbers upto 255. In that case you may have to convert to a 16-Bit Integer or just a floating point number. You can convert back afterwards:
m1 = imread('owl.pgm');
m1 = double(m1);
m1 = min(255,m1+50);
m1 = uint8(m1);

How can I access my vectors indices when I am assigning values?

I am trying to code something in Matlab and it involves a lot of accessing elements in vectors. Below is a snippet of code that I am working on:
x(1)=1;
for i=2:18
x(i)=0;
end
for i=1:18
y(i)=1;
end
for i = 0:262124
x(i+18+1) = x(i+7+1) + mod(x(i+1),2);
y(i+18+1) = y(i+10+1) + y(i+7+1) + y(i+5+1) + mod(y(i+1), 2);
end
% n can be = 0, 1, 2,..., 262142
n = 2;
for i = 0: 262142
z(i+1) = x(mod(i+n+1, 262143)); %error: Subscript indices must either be real positive integers or logicals.
end
In the last "for" loop where I am initialising vector z(), I get an error saying: "Subscript indices must either be real positive integers or logicals." However, when I do not suppres z(i+1) by ommiting the semi colon, the program is able to run, and I can see the values of z in the workspace. Why is this?
The code I am writing in Matlab is based upon the series of instructions shown in the image below. However, I can't seem to track down my error which leads to me not being able to access the elements of x() (without not suppressing the output of z()).
I appreciate any ideas :-) Thank you!
The code breaks at that loop last iteration because , for i=262140 you get
(mod(i+n+1, 262143)) = 0
so you cant access x(0) in matlab. the first elements of any variable is x(1).
In addition, and not related to your question, this code doesn't use the advantages matlab has, instead of
for i=2:18
x(i)=0;
end
you can just write:
x(2:18)=0;
etc

calculating mean gray level

I have a lot of images in IM{}. I want to calculate mean graylevel of non-black pixels. When I run my code sum has 255 as a maximum value. I don't understand the reason. Why doesn't sum get higher values?
for i=1: length(IM)
[L,W,z]=size( IM{i});
k=1;
sum=0;
for L=1:L
for W=1: W
if IM{i}(L,W)~=0;
sum=IM{i}(L,W)+sum;
k=k+1;
end
end
end
Mean(i)=sum/k
end
That's probably because IM is of type uint8. This data type can't hold values larger than 255. Example:
>> uint8(200) + uint8(200)
ans =
255
To avoid this, you should convert IM to double:
IM = double(IM);
Anyway, your code could be reduced to a single line (including the conversion):
result = mean(double(IM(IM>0)));
With this approach, you could even dispense with double, because mean (actually sum, which is called by mean) converts to double automatically:
result = mean(IM(IM>0));

Index out of bounds because of numel MATLAB

I am trying to create bit scales images. I am getting an error with this code. What is wrong?
clc
clear all
a=imread('image.tif');%read file
[row col]=size(a);%row of image and column of image
b=zeros(row,col,8);%3D 0 matrix
for k=1:8%position of bit
for i=1:row%for every row
for j=1:col%for every column
bits = de2bi(a(i,j));
b(i,j,k)=bits(k);
end%endFor
end%endFor
end%endFor
for k=1:8
subplot(3,3,k);
imshow(b(:,:,k));
title(strcat(num2str(k),'. bit'));
end%endFor
ERROR:
??? Attempted to access bits(2); index out of bounds because numel(bits)=1.
Error in ==> soru1 at 13
b(i,j,k)=bits(k);
At this line of code:
bits = de2bi(a(i,j));
You are calling de2bi on the value of the pixel at "i,j". Presuming that the image you are opening is of type uint8, the value of a(i,j) can be anywhere between 0 and 255. If these values are 0 or 1, the output of de2bi as you call it is just "0" or "1" - that is, it only has one element in it, and you cannot access the second, non-existent element.
To correct this, you need to force the size of the output of de2bi to be the size you require, which can be done using a second input, like this:
bits = de2bi(a(i,j),8)
In fact the loop isn't required since de2bi, like most MATLAB functions, can handle vectors or matrices as input, not just single numbers:
a=imread('image.tif');
b=de2bi(a);
b = reshape(de2bi,[size(a),8]);

bitxor operation in MATLAB

I am trying to understand why the original image is not coming with this code. The resulting image receive is yellowish in color, instead of being similar to the image Img_new.
Img=imread(‘lena_color.tif’);
Img_new=rgb2gray(img);
Send=zeroes(size(Img_new);
Receive= zeroes(size(Img_new);
Mask= rand(size(Img_new);
for i=1 :256
for j=1:256
Send(i,j)=xor( Img_new(i,j),mask(i,j));
End
End
image(send);
imshow(send);
for i=1 :256
for j=1:256
receive(i,j)=xor( send(i,j),mask(i,j));
End
End
image(receive);
imshow(receive);
What am I doing wrong?
There are several problems in your code.
MATLAB is case sensitive so end and End is not the same. Same goes for receive, and send.
MATLAB has a lot of matrix-based operations so please use for loops as a last resort since most of these operations can be executed by MATLAB's optimized routines for matrices.
MATLAB's xor returns the logical xor so when it sees two values (or matrices of values) it doesn't matter if it's 234 xor 123 or 12 xor 23 since it is equivalent to 1 xor 1 and 1 xor 1. You're looking for bitxor which does the bitwise xor on each element of the matrix and I've used it in my code below. This is the only way you can retrieve the information with the pixel == xor(xor(pixel,key),key) operation (assuming that's what you want to do).
rand returns a real value from 0 - 1 ; therefore, to do a successful bitwise xor, you need numbers from 0 - 255. Hence, in my code, you'll see that mask has random values from 0-255.
Note: I've used peppers.png since it's available in MATLAB. Replace it with lena_color.tif.
%%# Load and convert the image to gray
img = imread('peppers.png');
img_new = rgb2gray(img);
%%# Get the mask matrix
mask = uint8(rand(size(img_new))*256);
%%# Get the send and receive matrix
send = bitxor(img_new,mask);
receive = bitxor(send,mask);
%%# Check and display
figure;imshow(send,[0 255]);
figure;imshow(receive,[0 255]);
Update:
%%# Get mask and img somehow (imread, etc.)
img = double(img);
mask_rgb = double(repmat(mask,[1 1 3]));
bitxor(img,mask);
If instead, you choose to make everything uint8 instead of double, then I urge you to check if you are losing data anywhere. img is uint8 so there is no loss, but if any of the values of mask is greater than 255 then making it double will lead to a loss in data.