Tạo đa giác Thiessen (Voronoi) bằng cách sử dụng các dòng (chứ không phải điểm) làm các tính năng đầu vào?


24

Tôi có một tập hợp các tính năng đường bên trong một ranh giới đa giác cụ thể. Đối với mỗi dòng, tôi muốn tạo một đa giác bên trong mà mọi điểm có thể gần với đường đã cho hơn bất kỳ dòng nào khác trong lớp. Trước đây tôi đã thực hiện điều này cho các tính năng nhập điểm bằng cách sử dụng tam giác Delaunay, nhưng nếu có một quy trình tương tự để thực hiện với các tính năng đường thì tôi không thể tìm thấy nó.

ETA: Giải pháp của Geogeek đã xảy ra với tôi, nhưng trong các phần cứng hơn, nơi các dòng đầu vào có ít đỉnh hơn, các đa giác kết quả sẽ tiến quá gần (thậm chí chồng chéo) một dòng mà chúng không nên. Ở đây, các đường màu đỏ là đầu vào của tôi, bạn có thể thấy các đỉnh và đa giác Thiessen được tạo từ chúng.

nhập mô tả hình ảnh ở đây

Có lẽ một giải pháp nhanh chóng và (rất) bẩn có thể là chuyển đổi từng dòng thành một tập hợp các điểm cách đều nhau (chứ không phải chỉ các đỉnh của dòng), tạo ra các đa giác Thiessen từ các dòng đó, sau đó hòa tan chúng dựa trên ID dòng gốc.


4
Biểu đồ Voronoi bao gồm các phân đoạn dòng cùng với các điểm không bao gồm "đa giác"; thay vào đó, các tế bào của chúng có ranh giới có thể bao gồm các phần của parabolas. Vì lý do này, một trong những cách hiệu quả và chính xác nhất để tạo ra các phần tử Voronoi là sử dụng biểu diễn raster. ESRI gọi thủ tục này Phân bổ Euclide .
whuber

Câu trả lời:


11

Để minh họa một giải pháp xử lý raster / hình ảnh, tôi bắt đầu với hình ảnh được đăng. Nó có chất lượng thấp hơn nhiều so với dữ liệu gốc, do sự chồng chất của các chấm màu xanh, đường màu xám, vùng màu và văn bản; và sự dày lên của các đường màu đỏ ban đầu. Do đó, nó đưa ra một thách thức: tuy nhiên, chúng ta vẫn có thể thu được các tế bào Voronoi với độ chính xác cao.

Tôi đã trích xuất các phần có thể nhìn thấy của các tính năng tuyến tính màu đỏ bằng cách trừ màu xanh lục khỏi kênh màu đỏ, sau đó làm giãn và ăn mòn các phần sáng nhất bằng ba pixel. Điều này đã được sử dụng làm cơ sở cho việc tính toán khoảng cách Euclide:

i = Import["http://i.stack.imgur.com/y8xlS.png"];
{r, g, b} = ColorSeparate[i];
string = With[{n = 3}, Erosion[Dilation[Binarize[ImageSubtract[r, g]], n], n]];
ReliefPlot[Reverse@ImageData@DistanceTransform[ColorNegate[string]]]

Âm mưu cứu trợ

(Tất cả các mã được hiển thị ở đây là Mathicala 8.)

Xác định các "đường vân" rõ ràng - phải bao gồm tất cả các điểm tách hai ô Voronoi liền kề - và kết hợp lại chúng với lớp đường cung cấp hầu hết những gì chúng ta cần tiến hành:

ridges = Binarize[ColorNegate[
   LaplacianGaussianFilter[DistanceTransform[ColorNegate[string]], 2] // ImageAdjust], .65];
ColorCombine[{ridges, string}]

Hình ảnh kết hợp

Dải màu đỏ đại diện cho những gì tôi có thể lưu của dòng và dải màu lục lam cho thấy các đường vân trong biến đổi khoảng cách. (Vẫn còn rất nhiều rác do bị đứt trong chính đường ban đầu.) Những đường vân này cần được làm sạch và đóng lại thông qua một sự giãn nở thêm - hai pixel sẽ làm - và sau đó chúng ta có thể xác định các vùng được kết nối được xác định bởi các đường ban đầu và các đường vân giữa chúng (một số trong đó cần được kết hợp lại rõ ràng):

Dilation[MorphologicalComponents[
  ColorNegate[ImageAdd[ridges, Dilation[string, 2]]]] /. {2 -> 5, 8 -> 0, 4 -> 3} // Colorize, 2]

Điều này đã đạt được, trong thực tế, là để xác định năm tính năng tuyến tính định hướng . Chúng ta có thể thấy ba tính năng tuyến tính riêng biệt phát ra từ một điểm hợp lưu. Mỗi cái đều có hai mặt. Tôi đã coi bên phải của hai tính năng ngoài cùng bên phải là giống nhau, nhưng mặt khác lại phân biệt mọi thứ khác, đưa ra năm tính năng. Các khu vực màu hiển thị biểu đồ Voronoi từ năm tính năng này.

Kết quả

Lệnh Phân bổ Euclide dựa trên một lớp phân biệt ba tính năng tuyến tính (mà tôi không có sẵn cho hình minh họa này) sẽ không phân biệt các mặt khác nhau của từng tính năng tuyến tính và do đó, nó sẽ kết hợp các vùng màu lục và màu cam ở bên trái ; nó sẽ chia tính năng teal ngoài cùng bên phải thành hai; và nó sẽ kết hợp những mảnh tách đó với các đặc điểm màu be và đỏ tươi tương ứng ở các mặt khác của chúng.

Rõ ràng, cách tiếp cận raster này có khả năng xây dựng các phần tử Voronoi của các tính năng tùy ý - điểm, mảnh tuyến tính và thậm chí đa giác, bất kể hình dạng của chúng - và nó có thể phân biệt các mặt của các tính năng tuyến tính.


1
Một giải pháp tương tự được minh họa tại mathicala.stackexchange.com/questions/20696/ .
whuber

5

Tôi nghĩ bạn có thể:

  • Chuyển đổi các đỉnh dòng thành các điểm (line_point).
  • Tạo đa giác voronoi bằng cách sử dụng các điểm (line_point).
  • Hòa tan các đa giác kết quả bằng cách sử dụng thuộc tính id đã được lưu từ lớp dòng hoặc bằng cách nối không gian với lớp dòng.

Tôi hy vọng tôi đã thực sự hiểu câu hỏi của bạn, nếu không bạn có thể cung cấp một bản vẽ để giải thích nhu cầu của bạn nhiều hơn.


2
Tôi nghĩ rằng bạn đã hiểu nó, và giải pháp đó đã xảy ra với tôi, nhưng bạn gặp phải vấn đề trong đó các đường có ít đỉnh hơn. Tôi sẽ cập nhật câu hỏi của tôi với một ảnh chụp màn hình.
Dan C

3
Điều này sẽ hoạt động tốt nếu bạn làm cho các điểm dày đặc hơn dọc theo đường. Mặc dù cách tiếp cận dựa trên raster (như whuber đề cập trong các bình luận về câu hỏi) tôi nghi ngờ sẽ hiệu quả hơn nhiều so với cách này.
Andy W
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.