First Derivative filter Matlab - matlab

I have recently been tasked with using a first derivative filter on an image of myself. The instructor said that I should first fix the value of y and preform f(x+1) - f(x) on the rows and then fix the new "X" values and preform f(y+1)-f(y) on the columns.
Note: I have been asked to do this task manually, not using filter2() or any other programmed function, so please do not suggest that I use filter2() or similar. Thanks!
I tried calling up all the pixels and subtracting each successive one by doing
fid = fopen('image.raw')
myimage = fread(fid,[512 683], '*int8')
fclose(fid)
imsz = size(myimage)
x = imsz(1)
for I = 1:512
for J = 1:683
X(I) - X(I-1) = XX
But it doesnt seem to work, and I dont quite understand why. If you could help me, or point me in the right direction, I would be very appreciative.

First of all, your code is syntatically incorrect:
There is no end statement to any of your loops, and besides, you don't even need loops here.
You seem to read your image into the variable myimage, but you're using an undefined variable X when attempting to calculate the derivative.
The order of your assignment statements is reversed. The variable you wish to assign to should be written in the left hand part of the assignement.
I strongly suggest that you read online tutorials and get yourself familiar with MATLAB basics before taking on more complicated tasks.
As to your specific problem:
MATLAB encourages vectorized operations, i.e operations on entire arrays (vectors or matrices) at once. To subtract adjacent values in an array, what you're basically doing is subtracting two arrays, shifted by one element with respect to each other. For one dimensional arrays, that would translate in MATLAB to:
a(2:end) - a(1:end-1)
where a is your array. The end keyword specifies the last index in the array.
To compute the derivative of an image (a 2-D matrix), you need to decide along which axis you want to perform that operation. To approximate the derivate along the y-axis, do this:
X(2:end, :) - X(1:end-1, :)
You can verify that this gives you the same result as diff(X, 1) (or simply diff(X)). To compute the approximate derivative along the x-axis, which is equivalent to diff(X, 2), do this:
X(:, 2:end) - X(:, 1:end-1)
The colon (:) is the same as writing 1:end as the array subscript for the corresponding dimension.

If your filtered image is div then
for Y = 1:682
for X = 1:511
div(X, Y) = myimage(X + 1, Y + 1) - myimage(X,Y);
end
end
Remember the last row and the last column are not filtered!

Related

Iterating a function in MATLAB

Incredibly simple question, but I think I'm unable to come up with the correct terminology to google search it.
If I have a snippet of code that relies on three independent variables:
code(x,y,z)
That produces two values, i.e.:
output1, output2
How do I go about iterating like so (pseudocode):
for x
for y
for z
code(x,y,z)
end
end
end
And have data I can parse to generate 3D graphs such as
surf(x,y,output1)
A naive solution I came up with was just to create a bin of n length and then iterating one variable n times to come up with a 2D graph, i.e:
x_axis = zeros(1,25)
for m = 1:25
xm = x + 1
x_axis(m) = xm
code(x,y,z)
Even a referral to some documentation would be extremely helpful.
Thanks!
Brute force approach:
for x=[1:50]
for y=[1:50]
for z=[1:50]
result(y,x,z)=code(x,y,z);
end
end
end
More paradigmatic approach (in MATLAB) is to meshgrid it, and pump those in.
[XX,YY,ZZ]=meshgrid([1:50],[1:50],[1:50]);
result=code(XX,YY,ZZ);

How to make a vector like vec(x) in MATLAB?

I am trying to replicate this formula:
I have gathered all variables in my workspace. However estimating vec(Theta') does not seem to work and so I am a little bit stuck.
Theta = A*B-C;
vTheta = vec(Theta');
A, B and C are defined. The problem is that MATLAB does not seem to know the function vec to do what I would like to do with Theta as in the formula.
How to fix this?
I don't know where you got that equation from, but vec is a function in R, maybe it's related to that? If you want to convert a matrix Theta into a vector, do
Theta(:)
Edit: If you need to transpose the matrix first, MATLAB might not let you do Theta'(:). Instead do it in two steps:
tmp = Theta'; tmp(:)
As written above the Colon Operator is the way vectorize defined variable.
Yet, sometime we want to vectorize a sub set of a variable.
Let's say we have a matrix - mA and we'd like to vectorize a sub section of it - mA(2:3, 4:7).
One way is to define a new variable and vectorize it:
vA = mA(2:3, 4:7);
vA = vA(:);
Yet, what if we only wanted to use this inside another expression and only once?
Could we escape the need to generate explicit variable?
Well, unfortunately MATLAB doesn't have the view() functionality like in Julia.
Yet if you want to avoid explicitly naming new variable (I'm not sure if MATLAB's JIT Engine can also void the memory allocation as Julia) you can do:
reshape(mA(2:3, 4:7), [], 1)
This will always yield a column vector.
You can also use:
reshape(mA(2:3, 4:7), 1, [])
To generate row vector.
For instance you can do:
reshape(mA(2:3, 4:7), 1, []) * reshape(mA(2:3, 4:7), [], 1, )
This will be the sum of squared values of those elements.

MATLAB: The "dot operator" versus using a "for loop"

I'm a bit of a beginner at matlab so I'm having a some trouble understanding differentiating a dot operator and a for loop.
Given a Column vector (it's a pretty long column vector). We are given the following equation...
f(x)=0.2*x^3 + (1/3)*(x^2-1) + 2*cos(x)+3*cos(10x)
I need to use the method of dot operator and a for loop to create 2 plots and also the time (using tic, toc)
However, with dot operator does it mean using
.^ or .*
in the equation? and if this is the case, wouldn't I still need to use that in order to make a for loop?
Any clarification or assistance would be greatly appreciated! I don't really understand how I would write these...
The operators prefixed with a dot are called element-wise operators. It performs the operation on each element of the arrays (after checking that all involved arrays have the same number of elements). So you don't need a for-loop with using this operator, this is implied. This is called vectorization.
For example:
C = A.*B;
is equivalent to:
C = zeros(size(C));
for i=1:numel(A)
C(i) = A(i)*B(i);
end
but the first one is heavily optimized. So it's strongly advised to use vectorized operators as much as possible.
your x is an vector of defined length and step size, for example it can be:
x = 1:1:100 %generates 1,2,3....100
x = 1:0.1:10 %generates 0.1,0.2,0.3....10
so if you want to write a function of x (which is a vector), for speed purposes, you might want to use the dot-product denoted by .* in matlab. In your case you can do:
f(x)=0.2.*x.^3 + (1/3).*(x.^2-1) + 2.*cos(x) +3.*cos(10x)
The more costly way to compute is to use a for loop:
for x = 1:100
f(x)=0.2*x^3 + (1/3)*(x^2-1) + 2*cos(x) +3*cos(10x)
end
figure
plot(f)
The problem in your for loop is that you overwrite on the value of fx2, in each iteration you give it a new value but it always remain of size 1x1. For minimal change in your code you could do something like:
fx2=[];
for x = A(:,4)
fx2 = [fx2 0.2*x^3+(1/3)*(x^2-1)+2*cos(x)+3*cos(10*x)];
end
plot(x,fx2)
that way, you add a new value in the vector fx2 at each iteration instead of overwriting, (fx2 would be 1x1 then 1x2...). However be aware that this is not optimized at all because well there is a for loop that can be avoided but also because fx2's size changes at each iteration. Another better solution would be to predefine fx2 with the right size and then in the loop, change its ith value at the ith iteration.

Detect signal jumps relative to local activity

In Matlab, is it possible to measure local variation of a signal across an entire signal without using for loops? I.e., can I implement the following:
window_length = <something>
for n = 1:(length_of_signal - window_length/2)
global_variance(n) = var(my_signal(1:window_length))
end
in a vectorized format?
If you have the image processing toolbox, you can use STDFILT:
global_std = stdfilt(my_signal(:),ones(window_length,1));
% square to get the variance
global_variance = global_std.^2;
You could create a 2D array where each row is shifted one w.r.t. to the row above, and with the number of rows equal to the window width; then computing the variance is trivial. This doesn't require any toolboxes. Not sure if it's much faster than the for loop though:
longSignal = repmat(mySignal(:), [1 window_length+1]);
longSignal = reshape(longSignal(1:((length_of_signal+1)*window_length)), [length_of_signal+1, window_length])';
global_variance = sum(longSignal.*longSignal, 2);
global_variance = global_variance(1:length_of_signal-window_length));
Note that the second column is shifted down by one relative to the one above - this means that when we have the blocks of data on which we want to operate in rows, so I take the transpose. After that, the sum operator will sum over the first dimension, which gives you a row vector with the results you want. However, there is a bit of wrapping of data going on, so we have to limit to the number of "good" values.
I don't have matlab handy right now (I'm at home), so I was unable to test the above - but I think the general idea should work. It's vectorized - I can't guarantee it's fast...
Check the "moving window standard deviation" function at Matlab Central. Your code would be:
movingstd(my_signal, window_length, 'forward').^2
There's also moving variance code, but it seems to be broken.
The idea is to use filter function.

matlab matrices and fold list

i have two problems in mathematica and want to do them in matlab:
measure := RandomReal[] - 0.5
m = 10000;
data = Table[measure, {m}];
fig1 = ListPlot[data, PlotStyle -> {PointSize[0.015]}]
Histogram[data]
matlab:
measure =# (m) rand(1,m)-0.5
m=10000;
for i=1:m
data(:,i)=measure(:,i);
end
figure(1)
plot(data,'b.','MarkerSize',0.015)
figure(2)
hist(data)
And it gives me :
??? The following error occurred
converting from function_handle to
double: Error using ==> double
If i do :
measure =rand()-0.5
m=10000;
data=rand(1,m)-0.5
then, i get the right results in plot1 but in plot 2 the y=axis is wrong.
Also, if i have this in mathematica :
steps[m_] := Table[2 RandomInteger[] - 1, {m}]
steps[20]
Walk1D[n_] := FoldList[Plus, 0, steps[n]]
LastPoint1D[n_] := Fold[Plus, 0, steps[n]]
ListPlot[Walk1D[10^4]]
I did this :
steps = # (m) 2*randint(1,m,2)-1;
steps(20)
Walk1D =# (n) cumsum(0:steps(n)) --> this is ok i think
LastPointold1D= # (n) cumsum(0:steps(n))
LastPoint1D= # (n) LastPointold1D(end)-->but here i now i must take the last "folding"
Walk1D(10)
LastPoint1D(10000)
plot(Walk1D(10000),'b')
and i get an empty matrix and no plot..
Since #Itamar essentially answered your first question, here is a comment on the second one. You did it almost right. You need to define
Walk1D = # (n) cumsum(steps(n));
since cumsum is a direct analog of FoldList[Plus,0,your-list]. Then, the plot in your code works fine. Also, notice that, either in your Mathematica or Matlab code, it is not necessary to define LastPoint1D separately - in both cases, it is the last point of your generated list (vector) steps.
EDIT:
Expanding a bit on LastPoint1D: my guess is that you want it to be a last point of the walk computed by Walk1D. Therefore, it would IMO make sense to just make it a function of a generated walk (vector), that returns its last point. For example:
lastPoint1D = #(walk) (walk(end));
Then, you use it as:
walk = Walk1D(10000);
lastPoint1D(walk)
HTH
You have a few errors/mistakes translating your code to Matlab:
If I am not wrong, the line data = Table[measure, {m}]; creates m copies of measure, which in your case will create a random vector of size (1,m). If that is true, in Matlab it would simply be data = measure(m);
The function you define gets a single argument m, therefor it makes no sense using a matrix notation (the :) when calling it.
Just as a side-note, if you insert data into a matrix inside a for loop, it will run much faster if you allocate the matrix in advance, otherwise Matlab will re-allocate memory to resize the matrix in each iteration. You do this by data = zeros(1,m);.
What do you mean by "in plot 2 the y=axis is wrong"? What do you expect it to be?
EDIT
Regarding your 2nd question, it would be easier to help you if you describe in words what you want to achieve, rather than trying to read your (error producing) code. One thing which is clearly wrong is using expression like 0:steps(n), since you use m:n with two scalars m and n to produce a vector, but steps(n) produces a vector, not a scalar. You probably get an empty matrix since the first value in the vector returned by steps(n) might be -1, and 0:-1 produces an empty vector.