2015-06-15 3 views
0

У меня возникли проблемы с интерполяцией и/или подгоночными сплайнами. Для моей проблемы есть два аспекта.интерполяционные или монтажные вопросы сплайна

Я выбираю точки на изображении вручную и хочу интерполировать точки между ними. Точки, на которые я нажимаю, фиксированы, и любая интерполяция ДОЛЖНА пройти через эти точки. Нет фиксированного количества очков. Одно изображение может иметь 5, другое может иметь 20 (хотя я сохраняю минимум 5). Точки не равномерно распределяются по одной линии, которая требует интерполяции. Фактически, большую часть времени есть большие пробелы, которые нужно заполнить. Все точки записываются как x и y значения координат с помощью:

[x,y] = ginput; 

Каждый (полный) сплайн должен иметь длину szG (обычно 100). Поэтому я вычислить x и y интерполянтов и yy восстанавливается как его накладывая на показателях изображения и участок/изображений перепутаны:

xx = min(x):(max(x)-min(x)-1)/(szG-1):max(x); 
yy = max(y):-(max(y)-min(y)-1)/(szG-1):min(y); 

Я затем рассчитать кривой:

newX = interp1(y,x,yy, 'cubic'); 
newY = interp1(x,y,xx, 'cubic'); 

Однако, когда я рисую их, интерполированная строка не проходит через начальные точки. На самом деле это довольно далеко.

Вторая проблема заключается в том, что часто две выбранные точки имеют одинаковые значения x или y. Это означает, что я получаю ошибку, когда дело доходит до интерполяции, поскольку значения должны быть разными.

Как вы можете обеспечить, чтобы интерполированная линия проходила через выбранные точки данных? Кроме того, как можно решить проблему с отдельными значениями?

ответ

0

Одна из проблем, с которыми вы сталкиваетесь, заключается в том, что вы не правильно меняете координаты изображения. Происхождение вашей оси должно находиться в верхнем левом углу, а не в левом нижнем углу, и поэтому просто отрицать ось yне выполнить эту работу за вас. Вы должны убедиться, что источник находится в левом верхнем углу, поэтому вам нужно взять координаты y и вычесть из общего количества строк, чтобы облегчить это. Тем не менее, трюк для изменения координат без необходимости делать это вручную - это сделать это на самой фигуре. Таким образом, вам не нужно беспокоиться о том, чтобы делать какие-либо вычисления для изменения оси y. Просто сделать это один раз фигура открыта:

axis ij; 

Чтобы вернуться к исходной системе, где начало координат находится в левом нижнем углу, просто сделать:

axis xy; 

Однако, если вы используете imshow в отобразите ваши изображения, тогда абсолютно нет необходимости изменять координаты y, потому что это уже действует, когда вы показываете изображение (ака axis ij вызывается под капотом).

Если вы хотите поменять местами координаты вручную самостоятельно, просто это предполагается, что ваш образ хранится в im:

y = size(im, 1) - y; 

Кроме того, вы не используете interp1 правильно.Вы указываете контрольные точки с x и y, и вы используете xx в качестве новых координат ввода. Вывод даст вам новыеy координаты, которые интерполируют вдоль этой линии, с xx, являющимися точками запроса, которые должны быть интерполированы. Поэтому вы можете просто использовать вывод interp1 непосредственно для вашего результата, и вам нужно только позвонить ему один раз.

Вот пример воспроизводимости. Предполагая, что у вас есть панель обработки изображений:

im = imread('cameraman.tif'); 
imshow(im); 
[x,y] = ginput(5); 

Здесь я выбираю 5 баллов. Обратите внимание, что мне не нужно менять ось y, потому что imshow уже делает это за вас. Я выбрал эти 5 координаты:

>> x 

x = 

    23.0000 
    71.0000 
    143.0000 
    200.0000 
    238.0000 

>> y 

y = 

    75 
    43 
    27 
    47 
    77 

Теперь давайте создадим сплайн из этих пунктов:

szG = 100; 
xx = min(x):(max(x)-min(x)-1)/(szG-1):max(x); 
yy = interp1(x, y, xx, 'cubic'); 

Если я могу сделать мелочью, вы можете сделать то же самое для ваших xx координат с помощью linspace по:

xx = linspace(min(x), max(x), szG); 

Теперь давайте покажем эти пункты, где находятся ключевые точки синего цвета с большими кругами и красным интерполированная линия:

hold on; 
plot(x, y, 'b.', 'MarkerSize', 16); 
plot(xx, yy, 'r'); 

Это то, что я получаю:

enter image description here

Я получаю точки, чтобы пройти через контрольные точки, и это, вероятно, потому, что вы не используете interp1 должным образом. Теперь, чтобы исправить проблему, где у вас есть дубликаты очков. Это не полезно вообще для interp1, поэтому я предлагаю отфильтровать любые 2D-точки, которые не уникальны, и вы можете сделать это, используя функцию unique. В частности, поместите координаты x и y в 2D-массив и отфильтруйте точки на основе строк. Таким образом, вы устраните любые неуникальные пары x и y для использования в interp1. Нечто подобное:

out = unique([x(:) y(:)], 'rows', 'stable'); 
x = out(:,1); 
y = out(:,2); 

unique также имеет побочный эффект, когда точки расположены в определенном порядке, таким образом, что первый столбец используется в качестве ключа сортировки. Вероятно, вы этого не хотите, и вы хотите сохранить тот же порядок очков, что и при нажатии на фигуру. Поэтому вам необходимо использовать флаг 'stable', чтобы этого не произошло. После этой операции x и y теперь будут содержать отличные координаты для использования в interp1.


Надеюсь, что это поможет. Удачи!

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