Berchin's FDLS arbitrary filter design algorithm - filtering

i'm trying to use Berchin's FDLS methods (for those that don't know what it is, it's a way to design arbitrary magnitude and phase of an IIR Eq)
I tried different things but neither gave me what i asked:
1) i tried to design an allpass filter with arbitrary phase response (nothing fancy just a linear phase and a short deviation for 5 points) and it didn't worked as planned.
2) i tried a linear phase response for a -12 db notch and the same way it didn't worked (in black the desired response)
a http://nsa34.casimages.com/img/2013/08/22/13082211272913316.jpg
i used a samplerate of 316, M=158 points and a filter order of around 50.
Do i need to use more points to increase the filter order or is it just impossible to design my filters using that algorithm?
thanks for you answers
Jeff

With FDLS, the parameters to play with to find alternate solutions, are not only the total filter order, but the ratio of zeros to poles. IIRC, more of both isn't always better (possibly for numerical reasons). So try smaller numbers of poles and zeros (only a few of each), increase the numbers separately, and see if you get a more appropriate match to your desired frequency response.

Related

Automatically truncating a curve to discard outliers in matlab

I am generation some data whose plots are as shown below
In all the plots i get some outliers at the beginning and at the end. Currently i am truncating the first and the last 10 values. Is there a better way to handle this?
I am basically trying to automatically identify the two points shown below.
This is a fairly general problem with lots of approaches, usually you will use some a priori knowledge of the underlying system to make it tractable.
So for instance if you expect to see the pattern above - a fast drop, a linear section (up or down) and a fast rise - you could try taking the derivative of the curve and looking for large values and/or sign reversals. Perhaps it would help to bin the data first.
If your pattern is not so easy to define but you are expecting a linear trend you might fit the data to an appropriate class of curve using fit and then detect outliers as those whose error from the fit exceeds a given threshold.
In either case you still have to choose thresholds - mean, variance and higher order moments can help here but you would probably have to analyse existing data (your training set) to determine the values empirically.
And perhaps, after all that, as Shai points out, you may find that lopping off the first and last ten points gives the best results for the time you spent (cf. Pareto principle).

DC part isolation

I have a signal consisting of fast oscillating AC part and slowly varying DC part. I need to calcuate its DC part (and envelope, but that's not important now).
I could use the STFT, filter and transform it back, but it's a little inefficient cause I am not looking for a whole spectrum. Any other ideas?
I have read the articles on MathWorks and my maths is good enough to design something general and complicated, but I am looking for tips, hints or smart and elegant simple solutions. Thanks in advance!
DC isolation is basically low-pass filtering. You want to remove all the high-frequency components, while preserving the low. There are tons of approaches to this problem, but it looks like you're looking for something quick and simple.
One of the simplest forms of low-pass filter is the moving average. It's messy in the frequency domain, but for many simple applications it is good enough, trivial to implement, and incredibly fast.
For reasons I'll get to later on, it isn't actually a very good low-pass filter when you consider the frequency domain, but it is a very good smoothing filter in the time domain, which is what it sounds like you need.
Update: After posting this, I realized this was asked with the MATLAB tag, not just signal-processing. I've added a bit at the end showing the simplest way to do it in MATLAB.
Moving Average Filter
Parameters:
N: Filter order, number of samples to average
Input:
xt: Input at time t. For negative t assume x is zero.
Output:
yt: Output at time t. This is the average of the previous N samples.
Algorithm
Initialization (t = 0)
y0 = x0 / N
At each time step (t > 0)
yt = *yt-1 + (xt - xt-N ) / N
Filter Frequency Response
The impulse response of the filter is a rectangular pulse the width of the filter order. This gives a straightforward frequency response:
H[f] = | sin(πfN) / (Nsin(πf)) |
This shows how horrible the frequency response is, but for many smoothing applications it doesn't really matter. The key thing to notice is that the first zero happens at f = 1/N. This gives you a good idea of what order filter to use in order to smooth out components above a specific frequency, as described in the next section.
Parameter Selection
Given a sampling rate fs and a cut-off frequency fc, the normalized cutoff frequency is simply f = fc / fs. This, plus the frequency response above, gives a simple way to come up with the filter order, although tweaking it slightly by hand may improve results:
N = 1/f = fs / fc
Another way to read this formula is that it is important that the filter order is smaller than the fastest DC feature that you wish to preserve. Otherwise it will be partially filtered out.
Time-Domain Response
To illustrate the time-domain response, I'll work through some examples. I'll be using a sample rate of fs = 1000.
I generated a 40ms rectangular pulse with noise added to demonstrate the effect of increasing the filter order.
As you can see, increasing the filter order smooths out the noise, but it has other effects as well. Higher orders mean a longer delay, and a slower response to step changes. Once the order gets too high, the results are worhtless. The N = 51 example shows what happens when the filter order is wider than the event that you want to capture.
Although those sloping edges may look bad, the moving average filter actually gives the steepest possible edges for a given amount of noise reduction that is possible for a linear filter of the same order, and due to the incredibly simple algorithm it is also the fastest linear filter to implement. Because it has only one parameter, it is also simple to tweak to find the optimal order for your application.
Other Tweaks and Implementation Tips
Multipass Filter
The simplest way to improve the moving average filter's response in the frequency domain is to run multiple passes. After a few runs it becomes a very good approximation of a Gaussian filter due ot the central limit theorem. This slows down the step response a bit, but it also rounds it off. Higher frequencies will be attenuated further, although it also affects the roll-off in the low-frequency end. The performance hit for adding a few more passes is minimal.
Circular Buffer
If you are processing a stream of data, then you don't always have an easy way to lookup xt-N. By using a circular buffer to keep track of the last N samples you end up with a simple way to look up the sample you need with only a few steps added to the algorithm - it preserves the constant-time per step regardless of filter order.
Roundoff Error
If you're working with fixed-point or integer values the roundoff can be completely eliminated. Simply don't divide by N in the filter algorithm:
at = *at-1 + xt - xt-N
yt = *at / N
However, you need to take care to make sure that this won't cause an overflow in a.
With floating-point values, the tiny rounding errors could add up over time. The simplest solution for a long-running filter is to calculate y by averaging the entire buffer of the last N samples every so often. This will reset you to a point where there is no accumulated error, while letting you use the fast algorithm for the vast majority of time steps.
Doing it in MATLAB
A moving average is a linear FIR filter with each weight set the same. This means the numerators are all the same and sum to one, and the denominator is 1. It's simple to use the filter function to perform a moving average:
y = filter(ones(1,N)/N, 1, x);
However, that isn't going to use the fast algorithm discussed above. If performance is an issue then you'll want to implement the algorithm yourself.

Different results for Fundamental Matrix in Matlab

I am implementing stereo matching and as preprocessing I am trying to rectify images without camera calibration.
I am using surf detector to detect and match features on images and try to align them. After I find all matches, I remove all that doesn't lie on the epipolar lines, using this function:
[fMatrix, epipolarInliers, status] = estimateFundamentalMatrix(...
matchedPoints1, matchedPoints2, 'Method', 'RANSAC', ...
'NumTrials', 10000, 'DistanceThreshold', 0.1, 'Confidence', 99.99);
inlierPoints1 = matchedPoints1(epipolarInliers, :);
inlierPoints2 = matchedPoints2(epipolarInliers, :);
figure; showMatchedFeatures(I1, I2, inlierPoints1, inlierPoints2);
legend('Inlier points in I1', 'Inlier points in I2');
Problem is, that if I run this function with the same data, I am still getting different results causing differences in resulted disparity map in each run on the same data
Pulatively matched points are still the same, but inliners points differs in each run.
Here you can see that some matches are different in result:
UPDATE: I thought that differences was caused by RANSAC method, but using LMedS, MSAC, I am still getting different results on the same data
EDIT: Admittedly, this is only a partial answer, since I am only explaining why this is even possible with these fitting methods and not how to improve the input keypoints to avoid this problem from the start. There are problems with the distribution of your keypoint matches, as noted in the other answers, and there are ways to address that at the stage of keypoint detection. But, the reason the same input can yield different results for repeated executions of estimateFundamentalMatrix with the same pairs of keypoints is because of the following. (Again, this does not provide sound advice for improving keypoints so as to solve this problem).
The reason for different results on repeated executions, is related to the the RANSAC method (and LMedS and MSAC). They all utilize stochastic (random) sampling and are thus non-deterministic. All methods except Norm8Point operate by randomly sampling 8 pairs of points at a time for (up to) NumTrials.
But first, note that the different results you get for the same inputs are not equally suitable (they will not have the same residuals) but the search space can easily lead to any such minimum because the optimization algorithms are not deterministic. As the other answers rightly suggest, improve your keypoints and this won't be a problem, but here is why the robust fitting methods can do this and some ways to modify their behavior.
Notice the documentation for the 'NumTrials' option (ADDED NOTE: changing this is not the solution, but this does explain the behavior):
'NumTrials' — Number of random trials for finding the outliers
500 (default) | integer
Number of random trials for finding the outliers, specified as the comma-separated pair consisting of 'NumTrials' and an integer value. This parameter applies when you set the Method parameter to LMedS, RANSAC, MSAC, or LTS.
MSAC (M-estimator SAmple Consensus) is a modified RANSAC (RANdom SAmple Consensus). Deterministic algorithms for LMedS have exponential complexity and thus stochastic sampling is practically required.
Before you decide to use Norm8Point (again, not the solution), keep in mind that this method assumes NO outliers, and is thus not robust to erroneous matches. Try using more trials to stabilize the other methods (EDIT: I mean, rather than switching to Norm8Point, but if you are able to back up in your algorithms then address the the inputs -- the keypoints -- as a first line of attack). Also, to reset the random number generator, you could do rng('default') before each call to estimateFundamentalMatrix. But again, note that while this will force the same answer each run, improving your key point distribution is the better solution in general.
I know its too late for your answer, but I guess it would be useful for someone in the future. Actually, the problem in your case is two fold,
Degenerate location of features, i.e., The location of features is mostly localized (on you :P) and not well-spread throughout the image.
These matches are sort of on the same plane. I know you would argue that your body is not planar, but comparing it to the depth of the room, it sort of is.
Mathematically, this means you are kind of extracting E (or F) from a planar surface, which always has infinite solutions. To sort this out, I would suggest using some constrain on distance between any two extracted SURF features, i.e., any two SURF features used for matching should be at least 40 or 100 pixels apart (depending on the resolution of your image).
Another way to get better SURF features is to set 'NumOctaves' in detectSURFFeatures(rgb2gray(I1),'NumOctaves',5); to larger values.
I am facing the same problem and this has helped (a little bit).

Process for comparing two datasets

I have two datasets at the time (in the form of vectors) and I plot them on the same axis to see how they relate with each other, and I specifically note and look for places where both graphs have a similar shape (i.e places where both have seemingly positive/negative gradient at approximately the same intervals). Example:
So far I have been working through the data graphically but realize that since the amount of the data is so large plotting each time I want to check how two sets correlate graphically it will take far too much time.
Are there any ideas, scripts or functions that might be useful in order to automize this process somewhat?
The first thing you have to think about is the nature of the criteria you want to apply to establish the similarity. There is a wide variety of ways to measure similarity and the more precisely you can describe what you want for "similar" to mean in your problem the easiest it will be to implement it regardless of the programming language.
Having said that, here is some of the thing you could look at :
correlation of the two datasets
difference of the derivative of the datasets (but I don't think it would be robust enough)
spectral analysis as mentionned by #thron of three
etc. ...
Knowing the origin of the datasets and their variability can also help a lot in formulating robust enough algorithms.
Sure. Call your two vectors A and B.
1) (Optional) Smooth your data either with a simple averaging filter (Matlab 'smooth'), or the 'filter' command. This will get rid of local changes in velocity ("gradient") that appear to be essentially noise (as in the ascending component of the red trace.
2) Differentiate both A and B. Now you are directly representing the velocity of each vector (Matlab 'diff').
3) Add the two differentiated vectors together (element-wise). Call this C.
4) Look for all points in C whose absolute value is above a certain threshold (you'll have to eyeball the data to get a good idea of what this should be). Points above this threshold indicate highly similar velocity.
5) Now look for where a high positive value in C is followed by a high negative value, or vice versa. In between these two points you will have similar curves in A and B.
Note: a) You could do the smoothing after step 3 rather than after step 1. b) Re 5), you could have a situation in which a 'hill' in your data is at the edge of the vector and so is 'cut in half', and the vectors descend to baseline before ascending in the next hill. Then 5) would misidentify the hill as coming between the initial descent and subsequent ascent. To avoid this, you could also require that the points in A and B in between the two points of velocity similarity have high absolute values.

High-pass filtering in MATLAB

Does anyone know how to use filters in MATLAB?
I am not an aficionado, so I'm not concerned with roll-off characteristics etc — I have a 1 dimensional signal vector x sampled at 100 kHz, and I want to perform a high pass filtering on it (say, rejecting anything below 10Hz) to remove the baseline drift.
There are Butterworth, Elliptical, and Chebychev filters described in the help, but no simple explanation as to how to implement.
There are several filters that can be used, and the actual choice of the filter will depend on what you're trying to achieve. Since you mentioned Butterworth, Chebyschev and Elliptical filters, I'm assuming you're looking for IIR filters in general.
Wikipedia is a good place to start reading up on the different filters and what they do. For example, Butterworth is maximally flat in the passband and the response rolls off in the stop band. In Chebyschev, you have a smooth response in either the passband (type 2) or the stop band (type 1) and larger, irregular ripples in the other and lastly, in Elliptical filters, there's ripples in both the bands. The following image is taken from wikipedia.
So in all three cases, you have to trade something for something else. In Butterworth, you get no ripples, but the frequency response roll off is slower. In the above figure, it takes from 0.4 to about 0.55 to get to half power. In Chebyschev, you get steeper roll off, but you have to allow for irregular and larger ripples in one of the bands, and in Elliptical, you get near-instant cut off, but you have ripples in both bands.
The choice of filter will depend entirely on your application. Are you trying to get a clean signal with little to no losses? Then you need something that gives you a smooth response in the passband (Butterworth/Cheby2). Are you trying to kill frequencies in the stopband, and you won't mind a minor loss in the response in the passband? Then you will need something that's smooth in the stop band (Cheby1). Do you need extremely sharp cut-off corners, i.e., anything a little beyond the passband is detrimental to your analysis? If so, you should use Elliptical filters.
The thing to remember about IIR filters is that they've got poles. Unlike FIR filters where you can increase the order of the filter with the only ramification being the filter delay, increasing the order of IIR filters will make the filter unstable. By unstable, I mean you will have poles that lie outside the unit circle. To see why this is so, you can read the wiki articles on IIR filters, especially the part on stability.
To further illustrate my point, consider the following band pass filter.
fpass=[0.05 0.2];%# passband
fstop=[0.045 0.205]; %# frequency where it rolls off to half power
Rpass=1;%# max permissible ripples in stopband (dB)
Astop=40;%# min 40dB attenuation
n=cheb2ord(fpass,fstop,Rpass,Astop);%# calculate minimum filter order to achieve these design requirements
[b,a]=cheby2(n,Astop,fstop);
Now if you look at the zero-pole diagram using zplane(b,a), you'll see that there are several poles (x) lying outside the unit circle, which makes this approach unstable.
and this is evident from the fact that the frequency response is all haywire. Use freqz(b,a) to get the following
To get a more stable filter with your exact design requirements, you'll need to use second order filters using the z-p-k method instead of b-a, in MATLAB. Here's how for the same filter as above:
[z,p,k]=cheby2(n,Astop,fstop);
[s,g]=zp2sos(z,p,k);%# create second order sections
Hd=dfilt.df2sos(s,g);%# create a dfilt object.
Now if you look at the characteristics of this filter, you'll see that all the poles lie inside the unit circle (hence stable) and matches the design requirements
The approach is similar for butter and ellip, with equivalent buttord and ellipord. The MATLAB documentation also has good examples on designing filters. You can build upon these examples and mine to design a filter according to what you want.
To use the filter on your data, you can either do filter(b,a,data) or filter(Hd,data) depending on what filter you eventually use. If you want zero phase distortion, use filtfilt. However, this does not accept dfilt objects. So to zero-phase filter with Hd, use the filtfilthd file available on the Mathworks file exchange site
EDIT
This is in response to #DarenW's comment. Smoothing and filtering are two different operations, and although they're similar in some regards (moving average is a low pass filter), you can't simply substitute one for the other unless it you can be sure that it won't be of concern in the specific application.
For example, implementing Daren's suggestion on a linear chirp signal from 0-25kHz, sampled at 100kHz, this the frequency spectrum after smoothing with a Gaussian filter
Sure, the drift close to 10Hz is almost nil. However, the operation has completely changed the nature of the frequency components in the original signal. This discrepancy comes about because they completely ignored the roll-off of the smoothing operation (see red line), and assumed that it would be flat zero. If that were true, then the subtraction would've worked. But alas, that is not the case, which is why an entire field on designing filters exists.
Create your filter - for example using [B,A] = butter(N,Wn,'high') where N is the order of the filter - if you are unsure what this is, just set it to 10. Wn is the cutoff frequency normalized between 0 and 1, with 1 corresponding to half the sample rate of the signal. If your sample rate is fs, and you want a cutoff frequency of 10 Hz, you need to set Wn = (10/(fs/2)).
You can then apply the filter by using Y = filter(B,A,X) where X is your signal. You can also look into the filtfilt function.
A cheapo way to do this kind of filtering that doesn't involve straining brain cells on design, zeros and poles and ripple and all that, is:
* Make a copy of the signal
* Smooth it. For a 100KHz signal and wanting to eliminate about 10Hz on down, you'll need to smooth over about 10,000 points. Use a Gaussian smoother, or a box smoother maybe 1/2 that width twice, or whatever is handy. (A simple box smoother of total width 10,000 used once may produce unwanted edge effects)
* Subtract the smoothed version from the original. Baseline drift will be gone.
If the original signal is spikey, you may want to use a short median filter before the big smoother.
This generalizes easily to 2D images, 3D volume data, whatever.