I have a small project on Moving object detection in moving camera in which i have to use negative optical flow vector to minimize ego motion compensation. I have a video and some particular consecutive frames in which average of negative optical flow vector has to be computed. I have already calculated Optical flow between say, (k-1)th and kth frame. Also, I have calculated average of optical flow vector V=[u,v], where v is the average of horizontal optical flow and u is the average of vertical flow. Now, I have to apply inverse of optical flow vector i.e., -V to the (k-1)th frame. I'm new to matlab and i don't know much about it. Please help
I have tried this code segment to do so but the results aren't as expected
function I1=reverseOF(I,V)
R=I(:,:,1);
G=I(:,:,2);
B=I(:,:,3);
[m,n]=size(rgb2gray(I));
for i=1:m
for j=1:n
v1=[j i];
v2=-V;
v3=v1.*v2;
R(floor(1+abs(v3(1,2))),floor(1+abs(v3(1,2))))=R(i,j);
G(floor(1+abs(v3(1,2))),floor(1+abs(v3(1,2))))=G(i,j);
B(floor(1+abs(v3(1,2))),floor(1+abs(v3(1,2))))=B(i,j);
I1(floor(1+abs(v3(1,2))),floor(1+abs(v3(1,2))))=I(i,j);
end
end
I1=cat(3,R,G,B);
enter code here
I have used abs() function because otherwise some error was occuring like "attempted to access negative location; index must be a positive or logical".
Image A and Image B are the images that i have used to estimate the optical flow.enter image description here
This is the result that i am obtaining after applying the above function.
enter image description here
Unfortunately, you cant do this easily. This is a quite advanced research problem, because obtaining the inverse of a vector field on a mesh grid is not an easy problem, actually its quite hard.
Notice that your vector field (optical flow) start in a mesh grid, but it doesnt end in a mesh grid, it ends in random subpixel positions. If you just invert this field, doing -V is not enough! The result wont be the inverse!
This is a open research problem, look for example at this 2010 paper that addresses exactly this issue, and proposes a method to create "pseudoinverses".
Suppose you have that inverse, because you computed it somehow. Your code is quite bad for it, and the solutions (abs!) are showing (no offense) that you are not really understanding what you are doing. For a known vector field {Vx,Vy}, size equals to the image size (if its not, you can figure out easily how to interpolate it unsig interp2 ) the code would look something like:
newimg=zeros(size(I));
[ix,iy]=meshgrid(1:size(I,1),1:size(I,2));
newimg(:,:,1)=interp2(I(:,:,1),ix+Vx,iy+Vy); % this is your whole loop.
newimg(:,:,2)=interp2(I(:,:,3),ix+Vx,iy+Vy); % this is your whole loop.
newimg(:,:,3)=interp2(I(:,:,2),ix+Vx,iy+Vy); % this is your whole loop.
Related
I'm trying to do a simulation of a 2-body mass-spring-damper. I've set up a state-space model that I'm pretty confident in and set an input of a displacement and velocity at the base in just one degree of freedom. Upon getting my outputs, I expected that the output vector would just be the state vector at each time step. However, when plotting the output vector corresponding to displacement for each mass in the vertical direction (the input direction), it looked much more like a velocity (0 at the extrema of the input). The plots are shown below:
When I integrated the top 2 plots, I got the following:
Now, I obviously can just accept the outputs as they are and assume I am right in my understanding. But, I want to be sure. From the documentation page:
lsim(___) also returns the time vector t used for simulation and the
state trajectories x (for state-space models only)
I'm just hoping to find out whether or not I am correct in that the output matrix columns correspond to the history of the state derivatives before I go base an analysis on a bad assumption.
I figured it out. My B-matrix expected [derivative, state,...] but I had them in the opposite order.
I took 200 projections at a step angle of 1.8 degrees using LabVIEW software. The size of the image is 2748 x 2748 pixels, uint16. Then using Matlab, I load the projection images, do the flat field correction, resize the image by 1/3 and save the images as .mat file. Then I run the code below for the filtered backprojection.
interp='linear'; %set interpolation: nearest, linear, spline, pchip, v5cubic
filter='Hann'; %set filter: Ram-Lak, Shepp-Logan, Cosine, Hamming, Hann, None
for s=1:916
for i=1:200
a(i,:)=proj065(:,s,i);
end
a=a';
%figure(3), imagesc(a)
b=iradon(a,1.8,interp,filter);
imagesc(b);
recon(:,:,s)=b;
s
clear a
end
If I used a filter in this code, I will get negative pixel values.
But, if I run the code without the filter, I will get positive pixel values.
Any idea why iradon returns negative pixel values in filtered back projection?
Thank you.
Nurul
Yes, the FBP (filtered back-projection) algorithm will do that. It can wrongly reconstruct voxels as having negative values, due to noise and discretization on the data. Nothing you can do about it than just crop those values generally.
As my PhD is about tomography reconstruction algorithms I feel contractually obligated (joking) to suggest the use of iterative algorithms to possibly obtain better images (never worse, often considerably better). Check SART/SIRT or CGLS for this problem.
However, you are calling your function wrong! In tomography, the step size is not enough to reconstruct an image, you generally need the exact angles, thus iradon doesnt accept a step size as an input, it accepts an array of angles.
in your case, theta should be theta=linspace(0,360-200/360,200), and you should call iradon(a,theta,...)
I want to evaluate the grid quality where all coordinates differ in the real case.
Signal is of a ECG signal where average life-time is 75 years.
My task is to evaluate its age at the moment of measurement, which is an inverse problem.
I think 2D approximation of the 3D case is hard (done here by Abo-Zahhad) with with 3-leads (2 on chest and one at left leg - MIT-BIT arrhythmia database):
where f is a piecewise continuous function in R^2, \epsilon is the error matrix and A is a 2D matrix.
Now, I evaluate the average grid distance in x-axis (time) and average grid distance in y-axis (energy).
I think this can be done by Matlab's Image Analysis toolbox.
However, I am not sure how complete the toolbox's approaches are.
I think a transform approach must be used in the setting of uneven and noncontinuous grids. One approach is exact linear time euclidean distance transforms of grid line sampled shapes by Joakim Lindblad et all.
The method presents a distance transform (DT) which assigns to each image point its smallest distance to a selected subset of image points.
This kind of approach is often a basis of algorithms for many methods in image analysis.
I tested unsuccessfully the case with bwdist (Distance transform of binary image) with chessboard (returns empty square matrix), cityblock, euclidean and quasi-euclidean where the last three options return full matrix.
Another pseudocode
% https://stackoverflow.com/a/29956008/54964
%// retrieve picture
imgRGB = imread('dummy.png');
%// detect lines
imgHSV = rgb2hsv(imgRGB);
BW = (imgHSV(:,:,3) < 1);
BW = imclose(imclose(BW, strel('line',40,0)), strel('line',10,90));
%// clear those masked pixels by setting them to background white color
imgRGB2 = imgRGB;
imgRGB2(repmat(BW,[1 1 3])) = 255;
%// show extracted signal
imshow(imgRGB2)
where I think the approach will not work here because the grids are not necessarily continuous and not necessary ideal.
pdist based on the Lumbreras' answer
In the real examples, all coordinates differ such that pdist hamming and jaccard are always 1 with real data.
The options euclidean, cytoblock, minkowski, chebychev, mahalanobis, cosine, correlation, and spearman offer some descriptions of the data.
However, these options make me now little sense in such full matrices.
I want to estimate how long the signal can live.
Sources
J. Müller, and S. Siltanen. Linear and nonlinear inverse problems with practical applications.
EIT with the D-bar method: discontinuous heart-and-lungs phantom. http://wiki.helsinki.fi/display/mathstatHenkilokunta/EIT+with+the+D-bar+method%3A+discontinuous+heart-and-lungs+phantom Visited 29-Feb 2016.
There is a function in Matlab defined as pdist which computes the pairwisedistance between all row elements in a matrix and enables you to choose the type of distance you want to use (Euclidean, cityblock, correlation). Are you after something like this? Not sure I understood your question!
cheers!
Simply, do not do it in the post-processing. Those artifacts of the body can be about about raster images, about the viewer and/or ... Do quality assurance in the signal generation/processing step.
It is much easier to evaluate the original signal than its views.
Due to the nature of my problem, I want to evaluate the numerical implementations of the Radon transform in Matlab (i.e. different interpolation methods give different numerical values).
while trying to code my own Radon, and compare it to Matlab's output, I found out that my radon projection sizes are different than Matlab's.
So a bit of intuition of how I compute the amount if radon samples needed. Let's do the 2D case.
The idea is that the maximum size would be when the diagonal (in a rectangular shape at least) part is proyected in the radon transform, so diago=sqrt(size(I,1),size(I,2)). As we dont wan nothing out, n_r=ceil(diago). n_r should be the amount of discrete samples of the radon transform should be to ensure no data is left out.
I noticed that Matlab's radon output is always even, which makes sense as you would want a "ray" through the rotation center always. And I noticed that there are 2 zeros in the endpoints of the array in all cases.
So in that case, n_r=ceil(diago)+mod(ceil(diago)+1,2)+2;
However, it seems that I get small discrepancies with Matlab.
A MWE:
% Try: 255,256
pixels=256;
I=phantom('Modified Shepp-Logan',pixels);
rd=radon(I,pi/4);
size(rd,1)
s=size(I);
diagsize=sqrt(sum(s.^2));
n_r=ceil(diagsize)+mod(ceil(diagsize)+1,2)+2
rd=
367
n_r =
365
As Matlab's Radon transform is a function I can not look into, I wonder why could it be this discrepancy.
I took another look at the problem and I believe this is actually the right answer. From the "hidden documentation" of radon.m (type in edit radon.m and scroll to the bottom)
Grandfathered syntax
R = RADON(I,THETA,N) returns a Radon transform with the
projection computed at N points. R has N rows. If you do not
specify N, the number of points the projection is computed at
is:
2*ceil(norm(size(I)-floor((size(I)-1)/2)-1))+3
This number is sufficient to compute the projection at unit
intervals, even along the diagonal.
I did not try to rederive this formula, but I think this is what you're looking for.
This is a fairly specialized question, so I'll offer up an idea without being completely sure it is the answer to your specific question (normally I would pass and let someone else answer, but I'm not sure how many readers of stackoverflow have studied radon). I think what you might be overlooking is the floor function in the documentation for the radon function call. From the doc:
The radial coordinates returned in xp are the values along the x'-axis, which is
oriented at theta degrees counterclockwise from the x-axis. The origin of both
axes is the center pixel of the image, which is defined as
floor((size(I)+1)/2)
For example, in a 20-by-30 image, the center pixel is (10,15).
This gives different behavior for odd- or even-sized problems that you pass in. Hence, in your example ("Try: 255, 256"), you would need a different case for odd versus even, and this might involve (in effect) padding with a row and column of zeros.
First I describe the physics, it is in a axisymmetric space, one sound source was placed at the original point, one sensor was placed on the axis under the source. Giving the source wave form, I try to get the sensor's waveform. all materiel parameter were known, for instance, sound speed, density.
I write the Matlab script to calculate it, by solving the sound propagation equation I can get
one function, say, A(w,k), w is frequency and k is wavenumber, this is so called frequency-wavenumber field. My matlab code like this,
discrete w and k, get a A array. first use FFT to k, get space and frequency information
then, FFT to w, get space and time information, that is the waveform at different point.
the fake code
for i_w=...
w=...
for i_k=...
k=...
M=A(w,k)
end
wave_space_freq=ifft(M)
end % here can specify the only point of the sensor
wave_space_freq=ifft(wave_space_freq)
My question is do I need to make conjugation and flip when I use IFFT,like ifft(M,0,fliplr(conj(M))) . because I saw some-others use them, but I don't understand why?
If you want a strictly real-valued result waveform (not complex with significant imaginary components), then the input to an IFFT has to be conjugate symmetric, such as:
ifft(dc_term,M,0,fliplr(conj(M))).