Подбор кривой в бинарном изображении, MATLAB

У меня есть это двоичное изображение bw:

введите здесь описание изображения

края объекта для выполнения некоторых измерений. Но сначала мне нужно сделать кривую для обоих краев. В результате должны получиться две плавные кривые, представляющие ребра.

У меня есть индексы для каждого ребра, но я не могу использовать их, чтобы сделать данные xy входными данными для подгоночной функции. Я имею в виду, что это не x и f(x), на самом деле все они имеют одно и то же значение (1) с разными позициями. Неправильно говорить [x y]=find(BW) ; y здесь не значение x, но наверняка должен быть способ использовать их для какого-то масштабирования бинарного изображения. Я кажусь смущенным, и я застрял здесь.

Есть рекомендации?


person Mohamed Sayed    schedule 11.04.2016    source источник
comment
Вы хотите получить (x,y) координаты каждого пикселя, принадлежащего линии, а затем подобрать функцию [x;y]=f(t)   -  person Jonas    schedule 11.04.2016


Ответы (1)


Почему бы не использовать polyfit?

[y x] = find( bw );  %// get x y coordinates of all curve points

Здесь нужно использовать две маленькие «уловки»:

  1. У вас есть две кривые, поэтому вам нужно разделить точки данных на левую и правую кривые.

    right = x<300;
    xr = x(right);
    yr = y(right);
    xl = x(~right);
    yl = y(~right);
    
  2. Так как ваши кривые близки к вертикальным, то лучше подогнать x=f(y), а не "классический" y=f(x):

    pr = polyfit( yr, xr, 3 );  %// fit 3rd deg poly
    pl = polyfit( yl, xl, 3 ); 
    

Теперь вы можете построить их

yy = linspace( 1, size(bw,1), 50 );

figure; imshow(bw, 'border', 'tight' );
hold all
plot( polyval( pr, yy ), yy, '.-', 'LineWidth', 1 );
plot( polyval( pl, yy ), yy, '.-', 'LineWidth', 1 );

И вы получаете:

введите здесь описание изображения

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

yy = 1:size(bw,1);  %// single value per row
xxr=polyval(pr,yy); %// corresponding column values
xxl=polyval(pl,yy);

Установите новую маску того же размера

nbw = false(size(bw)); 
nbw( sub2ind(size(bw),yy,round(xxr)) )=true;
nbw( sub2ind(size(bw), yy, round(xxl) )) = true; 

И результат

figure;imshow(nbw,'border','tight');

введите здесь описание изображения

person Shai    schedule 11.04.2016
comment
Это сработало, но только для построения графика, мне действительно нужно сделать индексы новых кривых логическими (единицами) в самом двоичном изображении, а не только в графике. Я пытался, но кажется, что я что-то упускаю, не могли бы вы помочь мне в этом последнем шаге? - person Mohamed Sayed; 11.04.2016
comment
@MohamedSayed вы можете получить значение столбца (X) для каждого значения строки (y), а затем округлить значения X, чтобы получить индексы - person Shai; 11.04.2016
comment
Я ценю вашу помощь, но, честно говоря, после моих испытаний я все еще не могу этого сделать. И я думаю, что точки будут дискретными или отдельными на бинарном изображении, а не на гладкой непрерывной кривой! - person Mohamed Sayed; 11.04.2016
comment
@MohamedSayed точки в двоичном изображении по определению дискретны. Вы не можете устанавливать пиксели в нецелочисленных местах - person Shai; 11.04.2016
comment
Я знаю, я не это имел в виду. Я имею в виду, что мне нужно иметь логическую для каждой строки. Другими словами, на кривой не должно быть пробелов ... В любом случае, когда я попробовал ваше предложение, вышли те же самые старые ребра, потому что для каждой строки есть несколько значений столбца, а не только одно. - person Mohamed Sayed; 11.04.2016