2014-02-13 4 views
2

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

В принципе, пусть

foo = 
    1  1  1 
    1  0  0 
    1  0  1 

вызова flood_fill(foo,1,1) даст

 1  1  1 
    1  0  0 
    1  0  0 

Теперь, я довольно новыми для Matlab. Первоначально я реализовал flood_fill в рекурсивном стиле, но поведение Matlab с поправкой на результат делало работу с большими изображениями очень неэффективными. Чтобы это исправить, я переписана flood_fill как этот

function [outImage] = flood_fill(inImage,start_x,start_y) 
    width = size(inImage,2); 
    height = size(inImage,1); 

    outImage = zeros(height,width); 

    points = []; 
    points = [points; [start_x start_y]]; 

    while size(points,1)>0 
     point = points(1,:); 
     points = points(2:end,:); 
     y=point(2); 
     x=point(1); 

     outImage(y,x)=1; 

     if (y>1 && (outImage(y-1,x)==0) && (inImage(y-1,x)==1)) 
      points = [points; [x y-1]]; 
     end 
     if (y<height && (outImage(y+1,x)==0) && (inImage(y+1,x)==1)) 
      points = [points; [x y+1]]; 
     end 
     if (x>1 && (outImage(y,x-1)==0) && (inImage(y,x-1)==1)) 
      points = [points; [x-1 y]]; 
     end 
     if (x<width && (outImage(y,x+1)==0) && (inImage(y,x+1)==1)) 
      points = [points; [x+1 y]]; 
     end 
    end 
end 

Теперь это работает на небольших матриц/изображений, но принимает навсегда на больших изображений, а также. Я подозреваю, почему происходит изменение размера массива. Обычно (например, на C++) я использовал бы неупорядоченный связанный список и использовал его как стек (удалить и вставить в голове), чтобы избежать дорогостоящих изменений массива.

Существует ли эквивалент такой структуры данных в Matlab? Если нет, что я могу использовать в Matlab-идиоме? Возможно, встроенная функция?

ответ

2

Функция, которую вы ищете называется bwselect:

foo=[1 1 1; 1 0 0; 1 0 1] 
b=bwselect(foo,1, 1) 

Обратите внимание, что вы можете определить также четвертый вход n (например, что: bwselect(foo,1,1,n)), что может иметь значение 4 для указания 4-связной области, или 8, чтобы указать область с 8 связями.

+0

Это именно то, что я искал, спасибо! Хотя он не отвечает на сам вопрос, он решает мою конкретную проблему. –

+0

Спасибо. Что касается самого вопроса, я не знаю для структуры с подобным списком в Matlab, но эта функция, например, является причиной для языков высокого уровня ... :) – Adiel

+0

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

1

Адиэль ответил на ваш второй вопрос «Возможно, встроенная функция?». Что касается первой части:

Я не знаком со связанными списками в MATLAB. Тем не менее, вы можете значительно ускорить свою функцию, инициализируя размер матрицы точек и не меняя размер после этого. Предварительная инициализация должна всегда быть выполнена в MATLAB. Если функция не будет работать с матрицами фиксированного размера, я всегда рекомендую вам попробовать переписать эту функцию.

Для вашего конкретного случая:

function [outImage] = flood_fill(inImage,start_x,start_y) 
    width = size(inImage,2); 
    height = size(inImage,1); 

    outImage = zeros(height,width); 

    points = zeros(nnz(inImage),2); % I take it this is the maximum size 
    points(1,:) = [start_x start_y]; 

    k = 1;       % Increment row number in points 
    while size(points,1)>0 

     k = k + 1; 
     y=points(k, 2); 
     x=points(k, 1); 

Я понимаю у вас есть навыки программирования в целом, так что я считаю, вы должны быть в состоянии адаптировать оставшийся код в новый формат. (У меня нет времени пройти через него и переписать его). Я совершенно уверен, что он запустит много быстрее!

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