Thuật toán xô xô điền tốt nhất là gì?


16

Tôi khá mới đối với việc xử lý hình ảnh và hiện tôi đang làm việc trên một ứng dụng giống như sơn sẽ có tính năng đổ xô. Tuy nhiên, tôi không biết thuật toán tốt nhất cho xô-điền là gì.

Tôi đã triển khai một ví dụ mà tôi tìm thấy từ trang web này , tuy nhiên, nó đã gặp phải các vấn đề về vòng lặp vô hạn khi người dùng cố gắng đổ đầy một khu vực đã được lấp đầy cùng màu.

Tôi hiện đang giải quyết vấn đề đó bằng cách điền trái, phải, lên rồi xuống; tuy nhiên, tôi đã làm cho nó để một khi pixel được điền vào bên trái, nó không thể điền vào bên phải, có nghĩa là các hình dạng như:

Thí dụ

sẽ không được điền đúng nếu công cụ xô được sử dụng tại dấu chấm màu đỏ.

Do đó, tôi hy vọng ai đó biết về một thuật toán hoặc một liên kết đến một thuật toán sẽ giải quyết tất cả các vấn đề này.

Thông tin bổ sung: Điều này sẽ được thực hiện bằng cách sử dụng Javascript làm công cụ vẽ. Nó sẽ được sử dụng trực tuyến sử dụng yếu tố Canvas.


Là vector hoặc bitmap dựa trên? Tôi đang giả sử bitmap bằng hình ảnh, nhưng chỉ cần đảm bảo ..
Demian Brecht

1
Tôi nghĩ rằng bạn đã thực hiện một cái gì đó không chính xác. Tôi đọc lướt tài liệu và theo các ví dụ hình ảnh, cái này sẽ điền vào hình ảnh như hình trên. Bạn đã sao chép và dán mã của anh ấy, hoặc bạn đã viết lại nó?
RLH

Hãy nghĩ đồ thị đi qua.
Bwmat

@RLH: Tôi sao chép và dán mã của anh ấy với một vài thay đổi để làm cho nó hoạt động với thiết lập của tôi.
Ivan

@Ivan: đừng bắt đầu tìm kiếm một thuật toán mới trước khi bạn giải quyết được các vấn đề "vòng lặp vô hạn". Nếu thậm chí không thể khắc phục điều đó đối với việc triển khai hiện có, bạn chắc chắn sẽ gặp nhiều rắc rối hơn khi bạn sẽ viết lại toàn bộ từ đầu.
Doc Brown

Câu trả lời:


21

Có vẻ như bạn thực sự đang tìm kiếm cái gọi là thuật toán Flood Fill. Đó có thể là lý do tại sao bạn không tìm thấy hàng tấn ví dụ cho nó. Có một số phương pháp Flood Fill được liệt kê trên trang Wikipedia cho thuật toán . Tôi đặc biệt khuyên dùng một trong những phương pháp không được đệ quy, 'xếp hàng'.


I highly recommend one of the non-recursive, 'queued' methods.- Bạn có thể giải thích tại sao?
Yêu tinh

1
@Elfayer Mỗi khi một hàm được gọi (giả sử "X ()" có lệnh gọi đến "Y ()"), các tham số và vị trí bộ nhớ từ hàm khởi tạo ("X ()") được lưu trữ trên ngăn xếp. Vì vậy, nếu bạn đang lấp đầy một không gian rộng lớn và phức tạp, thì sẽ có rất nhiều lệnh gọi hàm đệ quy. Tùy thuộc vào trình biên dịch và ngôn ngữ của bạn, điều này có thể dẫn đến chồng tràn hoặc tiêu thụ bộ nhớ quá mức.
boxcartenant

-1

Tôi hiện đang làm điều tương tự. Tuy nhiên, khi tôi gặp phải vấn đề mà bạn chỉ ra, tôi đã chọn cách đơn giản là kết thúc chức năng nếu công cụ được nhấp vào một khu vực có cùng màu bạn đang cố vẽ (đây dường như cũng là hành vi của ms-paint) .

Phương pháp xếp hàng phải cực kỳ trực quan cho bất kỳ ai có một số kinh nghiệm lập trình.

Nếu sơn khu vực xung quanh một điểm có cùng màu với màu sơn của bạn là một mối quan tâm, thì bạn có thể:

  • kiểm tra màu nền.
  • tìm kiếm các cạnh của điểm cùng màu mà bạn đã nhấp vào.
  • xếp hàng các điểm xung quanh đến chỗ.
  • tiến hành thực hiện bình thường bằng cách sử dụng (trong trường hợp này) hàng đợi đầy dấu chấm trắng.

Nếu bạn muốn bạn có thể xem mã (khá lúng túng) của tôi ở đây .

Nó không phải là nhanh nhưng nó hoạt động tốt ...


Tại sao các downvote? :( Tôi biết phương pháp này không đặc biệt "nhanh", nhưng nó hoạt động và cũng là giải pháp được đề xuất :(
Juan Pablo Alvarez Alfaro

1
bài này khá khó đọc (tường văn bản). Bạn có phiền chỉnh sửa ing nó thành một hình dạng tốt hơn?
gnat

2
Nghiêm túc? Mọi người bỏ phiếu xuống vì khó đọc? Tại sao không chọn chỉnh sửa? Nó không giống như nội dung có vấn đề.
l46kok

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.