2015-03-11 2 views
2

В настоящее время я пытаюсь найти способ перестановки векторов. Например, если у меня есть вектор размером 4 [1 3 5 7], и я хочу сжать его до размера 3, это даст мне [1 4 8] или что-то в этом роде. То же самое для увеличения, но наоборот.Matlab векторы передискретизации

Я искал и нашел функцию Interp и Decimate, который на самом деле сделать это, но проблема в том, что я не имею целое увеличение или сокращение коэффициента. У меня есть векторы размером от 140 до 160, и я хочу, чтобы все они имели размер 150. Это невозможно сделать с Interp или Decimate потому что они работают только с целыми коэффициентами.

Так что я задаюсь вопросом, есть ли какой-нибудь быстрый способ сделать это, или я действительно должен думать о умном способе сделать это переформирование?

Заранее спасибо

+2

'interp1' может это сделать. Также вы должны уточнить, что вы на самом деле хотите. Вы не * увеличиваете * и * сокращаетесь *, но передискретируете. И после того, как вы переустановили, вы не сможете вернуть свой оригинал ... – knedlsepp

+0

Но interp не принимает нецелое число как увеличивающий или уменьшающийся коэффициент, или я не использую Interp правильным способом? Потому что я использую его как interp (A, 150/140) – Delko

+0

'interp1' не принимает коэффициент масштабирования или уменьшения. Вы должны указать точки, которые хотите интерполировать на себя. – rayryeng

ответ

4

Если я правильно понимаю вашу проблему правильно, вы хотели бы Resample вектор данных. То, что вы можете сделать, это использовать interp1 в MATLAB, но вы указываете диапазон точек от начала, где вы хотите пробовать до конца, а количество точек в этом диапазоне - это общее количество точек для вашего желаемого результата.

Чтобы выполнить то, что вы хотите, используйте linspace. Кроме того, вы должны использовать массив, который хотите преобразовать в качестве значений или y, и вы должны использовать dummyx значения, которые определены для каждого значения в массиве, который вы пытаетесь выполнить повторно. Что-то простое, как x = [1 2 ... ] до такого количества элементов, как есть в вашем векторе, будет работать.

Работы с небольшим примером, сделайте следующее:

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 

Таким образом, для вашего конкретного случая, измените третью строку коды, так что 3 изменяются на 150. Определение a зависит от вас, но вторая строка кода и последняя строка кода должны оставаться неизменными.

Преимущество вышеуказанного подхода состоит в том, что вектор данных не предполагается увеличивать или уменьшать. На самом деле это может быть случайным. Что должно произойти, так это то, что ваши данные (сохраненные в a) будут повторно сэмплированы с учетом желаемого количества очков.

+1

Великие умы думают одинаково. – Ratbert

+0

@CrazyRat - Я согласен :). +1 для вас тоже. То, что вы сделали с 'linspace', становится более точным, чем то, что я сделал. Благодаря! – rayryeng

+0

Это действительно то, что я искал, большое спасибо! – Delko

1

Вы можете использовать linspace для создания линейно-разнесенных векторов с фиксированным числом элементов.

В вашем случае, я хотел бы выбрать для функции ручки на основе linspace для выполнения этой операции:

% --- 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 

Бест,

+0

Спасибо за ответ, это действительно работает, но элементы в моих векторах не обязательно линейно разнесенных между минимумом и максимумом. – Delko

3

Если у вас есть набор инструментов для обработки изображений, я хотел бы использовать

new_vector = imresize(old_vector, ratio); 

редактировать

Существует один Актуальный вопрос я только что заметил.Если отношение> 1, результат больше не является вектором, а матрицей. Его достаточно легко решить, так как каждая строка одинакова (это также работает, если отношение < = 1 так что его всегда безопасно использовать)

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

или чуть более изящным (заслуга 2cents)

new_vector = imresize(old_vector , [desired_num_rows desired_num_cols]) 
+1

Вам не нужно нормализовать данные на '[0,1]', если вход 'double' для' imresize'. Это не нужно. Попробуйте: 'B = imresize ([1 2; 3 4], 2);'. Вы увидите, что выход линейно интерполируется путем расширения входной матрицы 2 x 2 в 2 раза, и все данные являются плавающей точкой, а не внутри '[0,1]', поэтому вы можете удалить этот шаг нормализации , Если вы удалите это, ваш пост определенно более краткий и читабельный. – rayryeng

+1

Используя 'imresize', OP также может просто указать желаемую длину выходного вектора, а не коэффициент масштабирования, используя' B = imresize (A, [numrows numcols]) ' – Cecilia

+0

Я обновил свой ответ. Спасибо rayryeng, я так привык придерживаться определенных типов данных при работе с функциями обработки изображений, которые мне даже не придумали, чтобы попробовать что-то еще. 2cents, ваш комментарий был чрезвычайно полезен, спасибо! – andrew

Смежные вопросы