I have a matrix named IMG, it is a n * m * 3 shaped matrix (an hsv image). What I am trying to achieve is
IF IMG(x, y, 1) < 1/2
THEN IMG(X, Y, 2) = 0.
Logical indexing looks like a solution but with that way we can only access the condition index (IMG(x, y, 1)). With the code below I am changing first indices of the pixels but I want to change second one.
IMG( IMG(:, :, 1) > 1/2 ) = 0;
Thanks for your help.
One simple solution is to extract the whole plane, modify it, then put it back:
s = IMG(:, :, 2);
s(IMG(:, :, 1) > 1/2) = 0;
IMG(:, :, 2) = s;
It is also possible to play around with linear indices, which is more generic, but also more complex:
index = find(IMG(:, :, 1) > 1/2);
offset = size(IMG, 1) * size(IMG, 2);
IMG(index + offset) = 0;
You can multiply the image by a mask:
IMG(:, :, 2) = IMG(:, :, 2) .* (IMG(:, :, 1) <= (1/2)) ;
Or use compound assignment:
IMG(:, :, 2) .*= IMG(:, :, 1) <= (1/2);
Another fast option is reshaping the array:
sz =size(IMG) ;
IMG = reshape(IMG, [], 3);
IMG(IMG(:,1)>1/2, 1), 2) = 0;
IMG = reshape(IMG, sz) ;
Other, possibly less efficient, option is using ifelse :
IMG(:, :, 2) = ifelse(IMG(:, :, 1) > 1/2, 0, IMG(:, :, 2) ) ;
looking for another one-line solution without any intermediate holding variable, the following was proposed for a multi-dimensional array on the Octave Help list:
a( (a(:,:,3)<.5) & shiftdim(1:size(a,3)==2,-1) ) = 0
for example:
>> a = rand(2,3,3)
a =
ans(:,:,1) =
0.63416 0.28912 0.33463
0.76642 0.51474 0.28130
ans(:,:,2) =
0.99748 0.26000 0.45671
0.73153 0.44499 0.24099
ans(:,:,3) =
0.94726 0.77252 0.12698
0.27069 0.46458 0.55833
>> a( (a(:,:,3)<.5) & shiftdim(1:size(a,3)==2,-1) ) = 0
a =
ans(:,:,1) =
0.63416 0.28912 0.33463
0.76642 0.51474 0.28130
ans(:,:,2) =
0.99748 0.26000 0.00000
0.00000 0.00000 0.24099
ans(:,:,3) =
0.94726 0.77252 0.12698
0.27069 0.46458 0.55833
Related
I need to use the Kalman filter to fuse multi-sensors positions for gaussian measurement (for example 4 positions as the input of the filter and 1 position as output). It is possible to help me with some examples or tutorials because all the examples I found are related to the estimation of the positions?
OPTION 1
Weighted Avarage
In this case you don't need to implement a real Kalman Filter. You just can use the signal variances to calculate the weights and then calculate the weighted avarage of the inputs. The weights can be found as an inverse of the variances.
So if you have two signals S1 and S2 with variances V1 and V2, then the fused result would be
A fusion example can be seen on the next plot.
I simulated two signals. The variance of the second signal changes over the time. As long as it's smaller than the variance of the first signal the fused result is close to the second signal. It is not the case when the variance of the second signal is too high.
OPTION 2
Kalman Filter with Multiple Update Steps
The classical Kalman Filter uses prediction and update steps in a loop:
prediction
update
prediction
update
...
In your case you have 4 independent measurements, so you can use those readings after each other in separate update steps:
prediction
update 1
update 2
update 3
update 4
prediction
update 1
...
A very nice point is that the order of those updates does not matter! You can use updates 1,2,3,4 or 3,2,4,1. In both cases you should get the same fused output.
Compared to the first option you have following pros:
You have a variance propogation
You have the system noise matrix Q,
so you can control the smoothness of the fused output
Here is my matlab code:
function [] = main()
% time step
dt = 0.01;
t=(0:dt:2)';
n = numel(t);
%ground truth
signal = sin(t)+t;
% state matrix
X = zeros(2,1);
% covariance matrix
P = zeros(2,2);
% kalman filter output through the whole time
X_arr = zeros(n, 2);
% system noise
Q = [0.04 0;
0 1];
% transition matrix
F = [1 dt;
0 1];
% observation matrix
H = [1 0];
% variance of signal 1
s1_var = 0.08*ones(size(t));
s1 = generate_signal(signal, s1_var);
% variance of signal 2
s2_var = 0.01*(cos(8*t)+10*t);
s2 = generate_signal(signal, s2_var);
% variance of signal 3
s3_var = 0.02*(sin(2*t)+2);
s3 = generate_signal(signal, s3_var);
% variance of signal 4
s4_var = 0.06*ones(size(t));
s4 = generate_signal(signal, s4_var);
% fusion
for i = 1:n
if (i == 1)
[X, P] = init_kalman(X, s1(i, 1)); % initialize the state using the 1st sensor
else
[X, P] = prediction(X, P, Q, F);
[X, P] = update(X, P, s1(i, 1), s1(i, 2), H);
[X, P] = update(X, P, s2(i, 1), s2(i, 2), H);
[X, P] = update(X, P, s3(i, 1), s3(i, 2), H);
[X, P] = update(X, P, s4(i, 1), s4(i, 2), H);
end
X_arr(i, :) = X;
end
plot(t, signal, 'LineWidth', 4);
hold on;
plot(t, s1(:, 1), '--', 'LineWidth', 1);
plot(t, s2(:, 1), '--', 'LineWidth', 1);
plot(t, s3(:, 1), '--', 'LineWidth', 1);
plot(t, s4(:, 1), '--', 'LineWidth', 1);
plot(t, X_arr(:, 1), 'LineWidth', 4);
hold off;
grid on;
legend('Ground Truth', 'Sensor Input 1', 'Sensor Input 2', 'Sensor Input 3', 'Sensor Input 4', 'Fused Output');
end
function [s] = generate_signal(signal, var)
noise = randn(size(signal)).*sqrt(var);
s(:, 1) = signal + noise;
s(:, 2) = var;
end
function [X, P] = init_kalman(X, y)
X(1,1) = y;
X(2,1) = 0;
P = [100 0;
0 300];
end
function [X, P] = prediction(X, P, Q, F)
X = F*X;
P = F*P*F' + Q;
end
function [X, P] = update(X, P, y, R, H)
Inn = y - H*X;
S = H*P*H' + R;
K = P*H'/S;
X = X + K*Inn;
P = P - K*H*P;
end
And here is the result:
I want to build a function in the following way:
f[x_] := 0;
For[i = 1, i <= n, i++,
g[x_] := 0;
For[k = 1, k <= i, k++,
g ^:= g[#]*(# - X[[k]]) &;
g[x_] = g;
]
f ^:= f[#] + Q[[1, i]]*g[#];
f[x_] = f;
So I get a polynomial
Q_11 * (x-x_1) + Q_12 * (x-x_1) * (x-2x_2) ...
This is the latest version I have, but it does not work. The problem is that I have to add functions (I found some posts where it is done) but I have to save the new function so I can use it again.
Does someone know what to do?
Thanks!
Marius
I cant make head or tail of your code but you can readily construct that result just like this:
qlist = Array[q, {10, 10}];
xlist = Array[x, 10];
poly[n_] := Sum[ qlist[[1, j]] Product[ (x - xlist[[i]] ), {i, j}] , {j, 3}]
poly[3]
q[1, 1] (x - x[1]) + q[1, 2] (x - x[1]) (x - x[2]) +
q[1, 3] (x - x[1]) (x - x[2]) (x - x[3])
If you really need help using UpSetDelayed you should pose a more simple / specific question ( ie without the For loops. )
As a sub-routine for a script I'm writing, I need a numerical function that behaves in a specific pattern. It takes a single input and provides a single output, such that between 0 and L inclusive, it is the identity function, but then between L+1 and L*2+1, it returns L to 0 respectively, and then from L*2+2 to L*3+2 it returns 0 to L respectively, and so on. I want to do this without any if statements, only using absolute value and modulus. Can anyone give me pseudocode for this function?
Given input I, limit L and result R, and using only basic arithmetic and absolute values, this gives the desired result.
R = ABS(L * ((I - (I % (L + 1))) / (L + 1) % 2) + (L + 1) * (I - (I % (L + 1))) / (L + 1) - I)
This can obviously be hugely simplified by declaring some intermediate variables, and using additional methods, e.g. floor to simulate integer division. Here's a Javascript example:
var factor = Math.floor(input / (limit + 1));
var flag = factor % 2;
var result = Math.abs(limit * flag + (limit + 1) * factor - input)
I am trying to get the following code to do a few more tricks:
class App(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.answerLabel = Label(self, text="Output List:")
self.answerLabel.grid(row=2, column=1, sticky=W)
def psiFunction(self):
j = int(self.indexEntry.get())
valueList = list(self.listEntry.get())
x = map(int, valueList)
if x[0] != 0:
x.insert(0, 0)
rtn = []
for n2 in range(0, len(x) * j - 2):
n = n2 / j
r = n2 - n * j
rtn.append(j * x[n] + r * (x[n + 1] - x[n]))
self.answer = Label(self, text=rtn)
self.answer.grid(row=2, column=2, sticky=W)
if __name__ == "__main__":
root = Tk()
In particular, I am trying to get it to calculate len(x) * j - 1 terms, and to work for a variety of parameter values. If you try running it you should find that you get errors for larger parameter values. For example with a list 0,1,2,3,4 and a parameter j=3 we should run through the program and get 0123456789101112. However, I get an error that the last value is 'out of range' if I try to compute it.
I believe it's an issue with my function as defined. It seems the issue with parameters has something to do with the way it ties the parameter to the n value. Consider 0123. It works great if I use 2 as my parameter (called index in the function) but fails if I use 3.
EDIT:
def psi_j(x, j):
rtn = []
for n2 in range(0, len(x) * j - 2):
n = n2 / j
r = n2 - n * j
if r == 0:
rtn.append(j * x[n])
else:
rtn.append(j * x[n] + r * (x[n + 1] - x[n]))
print 'n2 =', n2, ': n =', n, ' r =' , r, ' rtn =', rtn
return rtn
For example if we have psi_j(x,2) with x = [0,1,2,3,4] we will be able to get [0,1,2,3,4,5,6,7,8,9,10,11] with an error on 12.
The idea though is that we should be able to calculate that last term. It is the 12th term of our output sequence, and 12 = 3*4+0 => 3*x[4] + 0*(x[n+1]-x[n]). Now, there is no 5th term to calculate so that's definitely an issue but we do not need that term since the second part of the equation is zero. Is there a way to write this into the equation?
If we think about the example data [0, 1, 2, 3] and a j of 3, the problem is that we're trying to get x[4]` in the last iteration.
len(x) * j - 2 for this data is 10
range(0, 10) is 0 through 9.
Manually processing our last iteration, allows us to resolve the code to this.
n = 3 # or 9 / 3
r = 0 # or 9 - 3 * 3
rtn.append(3 * x[3] + 0 * (x[3 + 1] - x[3]))
We have code trying to reach x[3 + 1], which doesn't exist when we only have indices 0 through 3.
To fix this, we could rewrite the code like this.
n = n2 / j
r = n2 - n * j
if r == 0:
rtn.append(j * x[n])
else:
rtn.append(j * x[n] + r * (x[n + 1] - x[n]))
If r is 0, then (x[n + 1] - x[n]) is irrelevant.
Please correct me if my math is wrong on that. I can't see a case where n >= len(x) and r != 0, but if that's possible, then my solution is invalid.
Without understanding that the purpose of the function is (is it a kind of filter? or smoothing function?), I prickled it out of the GUI suff and tested it alone:
def psiFunction(j, valueList):
x = map(int, valueList)
if x[0] != 0:
x.insert(0, 0)
rtn = []
for n2 in range(0, len(x) * j - 2):
n = n2 / j
r = n2 - n * j
print "n =", n, "max_n2 =", len(x) * j - 2, "n2 =", n2, "lx =", len(x), "r =", r
val = j * x[n] + r * (x[n + 1] - x[n])
rtn.append(val)
print j * x[n], r * (x[n + 1] - x[n]), val
return rtn
if __name__ == '__main__':
print psiFunction(3, [0, 1, 2, 3, 4])
Calling this module leads to some debugging output and, at the end, the mentionned error message.
Obviously, your x[n + 1] access fails, as n is 4 there, so n + 1 is 5, one too much for accessing the x array, which has length 5 and thus indexes from 0 to 4.
EDIT: Your psi_j() gives me the same behaviour.
Let me continue guessing: Whatever we want to do, we have to ensure that n + 1 stays below len(x). So maybe a
for n2 in range(0, (len(x) - 1) * j):
would be helpful. It only produces the numbers 0..11, but I think this is the only thing which can be expected out of it: the last items only can be
3*3 + 0*(4-3)
3*3 + 1*(4-3)
3*3 + 2*(4-3)
and stop. And this is achieved with the limit I mention here.
I'm trying to get x and y coordinates for points along a line (segment) at even intervals. In my test case, it's every 16 pixels, but the idea is to do it programmatically in ActionScript-3.
I know how to get slope between two points, the y intercept of a line, and a2 + b2 = c2, I just can't recall / figure out how to use slope or angle to get a and b (x and y) given c.
Does anyone know a mathematical formula to figure out a and b given c, y-intercept and slope (or angle)? (AS3 is also fine.)
You have a triangle:
|\ a^2 + b^2 = c^2 = 16^2 = 256
| \
| \ c a = sqrt(256 - b^2)
a | \ b = sqrt(256 - a^2)
| \
|__________\
b
You also know (m is slope):
a/b = m
a = m*b
From your original triangle:
m*b = a = sqrt(256 - b^2)
m^2 * b^2 = 256 - b^2
Also, since m = c, you can say:
m^2 * b^2 = m^2 - b^2
(m^2 + 1) * b^2 = m^2
Therefore:
b = m / sqrt(m^2 + 1)
I'm lazy so you can find a yourself: a = sqrt(m^2 - b^2)
Let s be the slop.
we have: 1) s^2 = a^2/b^2 ==> a^2 = s^2 * b^2
and: 2) a^2 + b^2 = c^2 = 16*16
substitute a^2 in 2) with 1):
b = 16/sqrt(s^2+1)
and
a = sqrt((s^2 * 256)/(s^2 + 1)) = 16*abs(s)/sqrt(s^2+1)
In above, I assume you want to get the length of a and b. In reality, your s is a signed value, so a could be negative. Therefore, the incremental value of a will really be:
a = 16s/sqrt(s^2+1)
The Point class built in to Flash has a wonderful set of methods for doing exactly what you want. Define the line using two points and you can use the "interpolate" method to get points further down the line automatically, without any of the trigonometry.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Point.html#interpolate()
The Slope is dy/dx. Or in your terms A/B.
Therefore you can step along the line by adding A to the Y coordinate, and B to the X coordinate. You can Scale A and B to make the steps bigger or smaller.
To Calculate the slope and get A and B.
Take two points on the line (X1,Y1) , (X2,Y2)
A= (Y2-Y1)
B= (X2-X1)
If you calculate this with the two points you want to iterate between simply divide A and B by the number of steps you want to take
STEPS=10
yStep= A/STEPS
xStep= B/STEPS
for (i=0;i<STEPS;i++)
{
xCur=x1+xStep*i;
yCur=y1+yStep*i;
}
Given the equation for a line as y=slope*x+intercept, you can simply plug in the x-values and read back the y's.
Your problem is computing the step-size along the x-axis (how big a change in x results from a 16-pixel move along the line, which is b in your included plot). Given that you know a^2 + b^2 = 16 (by definition) and slope = a/b, you can compute this:
slope = a/b => a = b * slope [multiply both sides by b]
a^2 + b^2 = 16 => (b * slope)^2 + b^2 = 16 [by substitution from the previous step]
I'll leave it to you to solve for b. After you have b you can compute (x,y) values by:
for x = 0; x += b
y = slope * x + intercept
echo (x,y)
loop