Каков наилучший алгоритм «заполнения корзины»?

16

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

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

В настоящее время я работаю над этой проблемой, заполняя налево, направо, вверх и затем вниз; тем не менее, я сделал так, чтобы после того, как пиксель был заполнен слева, он не может заполнить вправо, что означает такие формы, как:

пример

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

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

Дополнительная информация: Это будет реализовано с использованием Javascript в качестве инструмента рисования. Он будет использоваться онлайн с использованием элемента Canvas.

Иван
источник
Это вектор или растровое изображение? Я предполагаю растровое изображение, но просто проверяю ..
Демиан Брехт
1
Я думаю, что вы реализовали что-то неправильно. Я пролистал документ, и в соответствии с примерами изображений это должно заполнить изображения, как показано выше. Вы скопировали и вставили его код или переписали?
RLH
Подумайте об обходе графа.
Bwmat
@RLH: Я скопировал и вставил его код с несколькими изменениями, чтобы он работал с моими настройками.
Иван
@Ivan: не начинайте искать новый алгоритм, пока не решите свои проблемы с «бесконечным циклом». Если вы даже не можете это исправить для существующей реализации, вы наверняка столкнетесь с гораздо большими проблемами, когда собираетесь переписать все с нуля.
Док Браун

Ответы:

21

Похоже, вы на самом деле ищете то, что называется алгоритмом Flood Fill. Возможно, поэтому вы не нашли тонны примеров для этого. Есть несколько методов Flood Fill, перечисленных на странице Википедии для алгоритма . Я настоятельно рекомендую один из нерекурсивных, «поставленных в очередь» методов.

GrandmasterB
источник
I highly recommend one of the non-recursive, 'queued' methods.- Не могли бы вы объяснить, почему?
Elfayer
1
@Elfayer Каждый раз, когда вызывается функция (скажем, «X ()» вызывает «Y ()»), параметры и место в памяти исходной функции («X ()») сохраняются в стеке. Итак, если вы заполняете большое и сложное пространство, то будет много рекурсивных вызовов функций. В зависимости от вашего компилятора и языка это может привести к переполнению стека или чрезмерному потреблению памяти.
boxcartenant
-1

В настоящее время я делаю то же самое. Однако, когда я столкнулся с проблемой, на которую вы указали, я выбрал простое завершение функции, если инструмент щелкнул по области того же цвета, который вы пытаетесь нарисовать (это также похоже на поведение ms-paint) ,

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

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

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

Если хотите, можете взглянуть на мой (довольно смущающий) код здесь .

Это далеко не быстро, но работает нормально ...

Хуан Пабло Альварес Альфаро
источник
Почему отрицательные? :( Я знаю, что метод не особенно «быстрый», но он работает, а также делает предлагаемое решение :(
Хуан Пабло Альварес Альфаро
1
этот пост довольно трудно читать (стена текста). Не могли бы вы изменить его в лучшую форму?
комнат
2
Шутки в сторону? Люди массово проголосовали, потому что было трудно читать? Почему бы не выбрать для редактирования? Это не похоже на содержание проблематично.
16