Matlab resampling vectors

2020-04-12 10:13发布

问题:

I'm currently trying to find a way to resample vectors. So for example if I have a vector of size 4 [1 3 5 7] and I want to shrink it to size 3 it would give me [1 4 8] or something like that. Same for enlarging but in the opposite way.

I have searched and found the function Interp and Decimate, which actually do this, but the problem is that I don't have an integer enlarging or shrinking factor. I have vectors of size 140 to 160 and I want them all to be of size 150. This can't be done with Interp or Decimate because they only work with integer factors.

So I'm wondering, is there any fast way to do this or do I actually have to think of a clever way to do this reshaping?

Thanks in advance

回答1:

If I understand your problem correctly, you would like to resample a data vector. What you can do is use interp1 in MATLAB, but you specify a range of points from the beginning of where you want to sample to the end, and the number of points within this range is the total number of points for your desired output.

To accomplish what you want, use linspace. In addition, you would use the array you want to resample as the output or y values, and you would use dummy x values that are defined for each value in the array you are trying to resample. Something simple like x = [1 2 ... ] up to as many elements as there are in your vector would work.

Working with your small example, do this:

a = [1 3 5 7];
x = 1 : numel(a);
xp = linspace(x(1), x(end), 3); %// Specify 3 output points
y = interp1(x, a, xp)

y =

     1     4     7

Therefore, for your specific case, change the third line of your code so that 3 is changed to 150. Defining a is up to you, but the second line of code and last line of code should stay the same.

The advantage of the above approach is that the data vector is not assumed to be increasing or decreasing. In fact, it can be all random. What should happen is that your data (stored in a) will be resampled given your desired number of points.



回答2:

If you have the image processing toolbox i would use

new_vector = imresize(old_vector, ratio);

edit

There is one actual issue I just noticed. If ratio > 1 the result is no longer a vector but a matrix. Its easy enough to solve since every row is the same (this also works if ratio <=1 so its always safe to use)

new_vector = imresize(old_vector, ratio);
new_vector = new_vector(1,:);

or a bit more elegant (credit goes to 2cents)

new_vector  = imresize(old_vector , [desired_num_rows desired_num_cols])


回答3:

You can use linspace to create linearly-spaced vectors with a fixed number of elements.

In your case, I would opt for a function handle based on linspace to perform this operation:

% --- Define the function handle
fun = @(A, n) linspace(min(A), max(A), n);

% --- Demo
A = 1:2:280;       % A has 140 elements
B = fun(A, 150);   % B has now 150 elements, with the same min and max

Best,