Finding standard deviation of an image - matlab

Firstly, I want to find standard deviation of this image:
Secondly, I want to find standard deviation of all lines in the image.
But at the first step, somethings going wrong and I see this:
>> A = imread('C:\Users\PC\Desktop\deneme.jpg');
>> std (A);
Error using var (line 65)
First argument must be single or double.
Error in std (line 38)
y = sqrt(var(varargin{:}));
line 65: error(message('MATLAB:var:integerClass'));
line 38: y = sqrt(var(varargin{:}));
How can I solve this problem and what is the code of finding standard deviation of all lines in this image?

The error is very explicit:
First input argument must be single or double.
This happens because A is of type uint8. The input to std has to be floating point (single or double).
So: convert to double, and optionally divide by 255 to normalize values to the interval between 0 and 1:
std(double(A)/255)
Note that the above gives the standard deviation of each column. If you want the stantard deviation of the image considered as a whole, linearize to a column vector first:
std(double(A(:))/255)

Related

Matlab Histogram Function

I'm new to Matlab and for an assignment my professor is having the class write (complete really) a custom Matlab function for generating a histogram from a set of data. Essentially a new vector is being created, L which is being updated with the information from a 2D matrix M. The first column of L contains the information from M(i,j) and in a second column contains the count (total) of M(i,j) in the data set. I'm in need of some direction as to how to proceed next.
Below is where I'm at thus far:
function L = hist_count(M)
L = [ [0:255' zeros(256,1) ];
for i = 1:size(M,1)
for j = 1:size(M,2)
L(double(M(i,j))+1,2) = <<finish code here>>;
end
end
figure;
plot(L(:1),L(:2));
The <<finish code here>> section is where I'm stuck. I understand everything up to the point where I need to update L with the information.
Assistance is appreciated.
Note: Your initialization of your histogram L has the brackets mismatched.
Remove the second [ bracket in the code. In addition, the creation of the 0:255 vector is incorrect. Doing 0:255' transposes the single constant of 255, which means that it will still create a horizontal vector of 0:255 which will make the code fail. You should surround the creation of this vector with parantheses, then transpose that result. Therefore:
L = [ (0:255)' zeros(256,1) ];
Now onto your actual problem. Judging by your initialization of the histogram, there are 256 possible values so your input is most likely of type uint8, which means that the values in your data will only be from [0-255] in steps of 1. Recall that a histogram records the total number of times you see a value. In this case, you have a two column matrix where the first column tells you the value you want to examine and the second column tells you how many times you see that value in your data. Therefore, each row tells you which value you are examining in your data as well as how many times you have seen that value in your data. Note that the counts are all initialized to zero, so the logic is that every time you see a value, you need to access the right row corresponding to the data point, then increment that value by 1.
Therefore, the line is simply just accessing the current count and adding 1 to it... you then store it back:
L(double(M(i,j))+1,2) = L(double(M(i,j))+1,2) + 1;
M(i,j) is the value found at location (i,j) in your 2D data. The last question you have is why cast the intensity to double and add 1? You cast to double because the input may be an integer type. This means that any values that are beyond the dynamic range of the type will get saturated. Because your input is type uint8, any values beyond 255 will saturate to 255. In MATLAB, we index into rows and columns of a matrix starting at 1 and because the values will potentially start at value 0, this corresponds to row 1 of your histogram so you have to offset by 1. When we get to the most extreme case of value 255 for type uint8 for example, adding 1 to this using the native uint8 will saturate to 255, which means that the values of 254 and 255 get lumped into the same bin. Therefore, you must convert to some type that extends beyond the limits of uint8 and then you add by 1 to avoid saturation. double is usually done here as a default as it has higher precision than uint8, but any type that is higher than uint8 in precision is suitable.

Plotting piecewise functions in maple

How would I plot this function in maple?
f(x)= 1 if x is rational, 0 otherwise.
Also I want this to be within the interval 0<=x<=1
That function is not piecewise, and it cannot be plotted by any software. It's theoretically impossible. The best that you could do is plot a line segment from (0,1) to (1,1) to represent the rationals and another from (0,0) to (0,1) to represent the irrationals.
This is an old question now but is a good place to clarify just what a computer program could mean by "rational" and "irrational".
As a first attempt you could try to define your desired function this way:
f1 := x -> `if`(x::rational, 1, 0):
A few test cases seem to be giving us what we want:
> f1(3), f1(3/2), f1(Pi), f1(sqrt(2));
1, 1, 0, 0
However we then run into this:
> f1(1.5);
0
What gives? Since f(3/2)=1, we might expect f(1.5) to be the same. The explanation is that the check x::rational is checking that the input x is of the Maple type rational, which is an integer or a fraction. A Maple fraction is an ordered pair of integers (numerator and denominator) which is structurally different from a floating-point number.
A broader interpretation of the mathematical meaning of 'rational' would include the floating-point numbers. So we can broaden that definition and write:
f2 := x -> `if`(x::{rational,float}, 1, 0}:
and then we have the desired f2(1.5)=1.
But both of these are useless for plotting. When Maple plots something, it generates a set of sample points from the specified interval, all of which will be floating-point numbers. Of our previously-defined functions, f1 will then return zero for all these points, while f2 will return 1.
You won't do any better with other software. If you were to take a truly uniform sample of n points from some real interval, your resulting points would be irrational (in fact, transcendental). Almost all such numbers cannot be represented on a computer because they cannot be represented in any compact form, so any software that attempts such sampling will simply return a collection of n results with terminating decimal expansions.
As Carl suggested you can generate something resembling the plot you want with
> plot([0,1]);

Can a logical variable hold a NaN?

In the documentation paragraph for an internal MATLAB function (R2014a), I find the following1:
% GRP2IDX treats NaNs (numeric or logical), ...
This phrase implies that there is an X such that both isnan(X) and islogical(X) evaluate to true. This makes no sense to me. I certainly have not been able to generate such an X. For example:
>> X = true;
>> X(1, 1) = NaN;
NaN's cannot be converted to logicals.
My question: Is there some other way to interpret the line above that makes more sense?
1FWIW, the full paragraph is this:
% GRP2IDX treats NaNs (numeric or logical), empty strings (char or cell array
% of strings), or <undefined> values (categorical) in S as missing values and
% returns NaNs in the corresponding rows of G. Neither GN nor GL include
% entries for missing values.
For more content, if you have R2014a (or possibly R2013b), run open table2gidx, and scroll down in the Editor window that appears. (grp2idx is an internal function of table2gidx.)
No, despite what the help may seem to imply, logical values can only be be 0 (false) or 1 (true). See help logical or the documentation. NaN (not a number) is strictly a numeric datatype defined for floating-point values. It is defined under the IEEE 754 specification.
Additionally isnumeric(NaN) and isfloat(NaN) return true. And class(NaN) returns 'double'. You can obtain a single precision NaN as it is just a floating-point value: single(NaN).
Interpret it as "NaNs (in numeric or logical arrays)". Since NaNs do not occur in logical arrays, that bit is redundant, but that doesn't make it incorrect.

get vector which's mean is zero from arbitrary vector

as i know to get zero mean vector from given vector,we should substract mean of given vector from each memeber of this vector.for example let us see following example
r=rand(1,6)
we get
0.8687 0.0844 0.3998 0.2599 0.8001 0.4314
let us create another vector s by following operation
s=r-mean(r(:));
after this we get
0.3947 -0.3896 -0.0743 -0.2142 0.3260 -0.0426
if we calculate mean of s by following formula
mean(s)
we get
ans =
-5.5511e-017
actually as i have checked this number is very small
-5.5511*exp(-017)
ans =
-2.2981e-007
so we should think that our vector has mean zero?so it means that that small deviation from 0 is because of round off error?for exmaple when we are creating white noise or such kind off random uncorrelated sequence of data,actually it is already supposed that even for such small data far from 0,it has zero mean and it is supposed in this case that for example for this case
-5.5511e-017 =0 ?
approximately of course
e-017 means 10 to the power of -17 (10^-17) but still the number is very small and hypothetically it is 0. And if you type
format long;
you will see the real precision used by Matlab
Actually you can refer to the eps command. Although matlab uses double that can encode numbers down to 2.2251e-308 the precission is determined size of the number.
Use it in the format eps(number) - it tell you the how large is the influence of the least significant bit.
on my machine eg. eps(0.3) returns 5.5511e-17 - exactly the number you report.

Why inverse equality does not satisfy in MATLAB?

MATLAB does not satisfy matrix arithmetic for inverse, that is;
(ABC)-1 = C-1 * B-1 * A-1
in MATLAB,
if inv(A*B*C) == inv(C)*inv(B)*inv(A)
disp('satisfied')
end
It does not qualify. When I made it format long, I realized that there is difference in points, but it even does not satisfy when I make it format rat.
Why is that so?
Very likely a floating point error. Note that the format function affects only how numbers display, not how MATLAB computes or saves them. So setting it to rat won't help the inaccuracy.
I haven't tested, but you may try the Fractions Toolbox for exact rational number arithmetics, which should give an equality to above.
Consider this (MATLAB R2011a):
a = 1e10;
>> b = inv(a)*inv(a)
b =
1.0000e-020
>> c = inv(a*a)
c =
1.0000e-020
>> b==c
ans =
0
>> format hex
>> b
b =
3bc79ca10c924224
>> c
c =
3bc79ca10c924223
When MATLAB calculates the intermediate quantities inv(a), or a*a (whether a is a scalar or a matrix), it by default stores them as the closest double precision floating point number - which is not exact. So when these slightly inaccurate intermediate results are used in subsequent calculations, there will be round off error.
Instead of comparing floating point numbers for direct equality, such as inv(A*B*C) == inv(C)*inv(B)*inv(A), it's often better to compare the absolute difference to a threshold, such as abs(inv(A*B*C) - inv(C)*inv(B)*inv(A)) < thresh. Here thresh can be an arbitrary small number, or some expression involving eps, which gives you the smallest difference between two numbers at the precision at which you're working.
The format command only controls the display of results at the command line, not the way in which results are internally stored. In particular, format rat does not make MATLAB do calculations symbolically. For this, you might take a look at the Symbolic Math Toolbox. format hex is often even more useful than format long for diagnosing floating point precision issues such as the one you've come across.