Đo độ thẳng của một đoạn đường cong (được biểu diễn dưới dạng đa tuyến)


11

Tôi đang làm việc trên một thuật toán ghi nhãn đường viền độ cao tự động và một trong những yếu tố mà tôi muốn tính đến khi quyết định vị trí của các nhãn là mức độ "thẳng" của một đoạn đường viền cụ thể. Càng thẳng, nó càng có khả năng được sử dụng để đặt nhãn trên phân khúc đó.

Mỗi đường viền được thể hiện bằng một đường đa tuyến (nhưng có các điểm gần nhau như trông giống như một đường cong với mắt thường). Sau đó, tôi có một chiều dài cố định (chiều rộng của nhãn), giả sử, 100 pixel. Nếu tôi ngẫu nhiên (hoặc nói cách khác) chọn phân đoạn đường viền có chiều rộng 100 pixel, tôi muốn có thể nhận được giá trị định lượng bằng số của độ thẳng của nó (nói không cho phân đoạn đường viền hoàn toàn thẳng, một số giá trị lớn hơn 0 đối với không phân đoạn thẳng và giá trị này tăng khi độ vẹo tăng).

Tôi đã tìm kiếm xung quanh để tìm câu trả lời nhưng tôi không thể tìm thấy bất cứ điều gì thực sự hữu ích. Tôi sẽ biết ơn bất kỳ con trỏ.

Câu trả lời:


9

Câu trả lời phụ thuộc vào ngữ cảnh : nếu bạn sẽ chỉ điều tra một số lượng nhỏ các phân đoạn (giới hạn), bạn có thể có khả năng chi trả cho một giải pháp tính toán đắt tiền. Tuy nhiên, có vẻ như bạn sẽ muốn kết hợp tính toán này trong một số loại tìm kiếm cho các điểm nhãn tốt. Nếu vậy, sẽ có lợi thế lớn khi có một giải pháp hoặc là tính toán nhanh hoặc cho phép cập nhật nhanh chóng một giải pháp khi phân khúc dòng ứng cử viên bị thay đổi một chút.

Ví dụ: giả sử bạn có ý định tiến hành tìm kiếm có hệ thốngtrên toàn bộ thành phần được kết nối của một đường viền, được biểu diễn dưới dạng một chuỗi các điểm P (0), P (1), ..., P (n). Điều này sẽ được thực hiện bằng cách khởi tạo một con trỏ (chỉ mục vào chuỗi) s = 0 ("s" cho "start") và một con trỏ khác f (cho "kết thúc") là chỉ số nhỏ nhất cho khoảng cách (P (f), P (s))> = 100, và sau đó tiến s trong khoảng cách (P (f), P (s + 1))> = 100. Điều này tạo ra một đa tuyến ứng cử viên (P (s), P (s + 1) ..., P (f-1), P (f)) để đánh giá. Đã đánh giá "mức độ phù hợp" của nó để hỗ trợ nhãn, sau đó bạn sẽ tăng s thêm 1 (s = s + 1) và tiến hành tăng f lên (giả sử) f 'và s thành s' cho đến khi một lần nữa một đa tuyến ứng cử viên vượt quá mức tối thiểu span 100 được sản xuất, đại diện là (P (s '), ... P (f), P (f + 1), ..., P (f')). Làm như vậy, các đỉnh P (s) ... P (s ' Rất mong muốn rằng thể dục có thể được cập nhật nhanh chóng từ kiến ​​thức chỉ các đỉnh bị bỏ và thêm. (Quy trình quét này sẽ được tiếp tục cho đến khi s = n; như thường lệ, f phải được phép "quấn quanh" từ n trở về 0 trong quy trình.)

Xem xét này loại trừ nhiều biện pháp có thể có của thể dục ( trạng thái khúc khuỷnh , tình trạng khúc khuỷu , vv) mà nếu không có thể là hấp dẫn. Điều này dẫn đến chúng tôi ủng hộ các biện pháp dựa trên L2 , vì chúng thường có thể được cập nhật nhanh chóng khi dữ liệu cơ bản thay đổi một chút. Tương tự với Phân tích thành phần chính cho thấy chúng ta giải trí theo biện pháp sau (trong đó nhỏ hơn là tốt hơn theo yêu cầu): sử dụng giá trị nhỏ hơn trong hai giá trị riêng của ma trận hiệp phương saicủa tọa độ điểm. Về mặt hình học, đây là một thước đo độ lệch từ phía bên "điển hình" của các đỉnh trong phần ứng cử viên của đa tuyến. (Một giải thích là căn bậc hai của nó là bán trục nhỏ của elip đại diện cho những khoảnh khắc thứ hai của quán tính của các đỉnh của polyline.) Nó sẽ bằng zero chỉ dành cho bộ đỉnh thẳng hàng; mặt khác, nó vượt quá không. Nó đo độ lệch giữa hai bên trung bình so với đường cơ sở 100 pixel được tạo bởi điểm bắt đầu và kết thúc của một đa tuyến, và do đó có một cách hiểu đơn giản.

Vì ma trận hiệp phương sai chỉ có 2 nhân 2, nên các giá trị riêng được tìm thấy nhanh chóng bằng cách giải một phương trình bậc hai. Hơn nữa, ma trận hiệp phương sai là tổng của các đóng góp từ mỗi đỉnh trong một đa tuyến. Do đó, nó được cập nhật nhanh chóng khi các điểm bị loại bỏ hoặc thêm vào, dẫn đến thuật toán O (n) cho đường viền điểm n: điều này sẽ mở rộng tốt cho các đường viền chi tiết cao được hình dung trong ứng dụng.

Dưới đây là một ví dụ về kết quả của thuật toán này. Các chấm đen là các đỉnh của một đường viền. Đường màu đỏ là đoạn đa tuyến ứng cử viên tốt nhất có độ dài từ đầu đến cuối lớn hơn 100 trong đường viền đó. (Ứng cử viên rõ ràng trực quan ở phía trên bên phải không đủ dài.)

Nhân vật


Wow, bạn đã làm tôi mất ở đó :). Bạn đã đúng về tìm kiếm có hệ thống, tôi đã phải làm điều đó để có được tiếp tuyến của từng đỉnh đa giác / đa giác (nhãn ngang được ưu tiên cho các dọc), vì vậy về lý thuyết tôi có thể mở rộng tìm kiếm này để bao quát các phép đo khác. BTW: bạn đã tạo ra âm mưu mẫu bằng thuật toán thực tế hay thủ công chưa?
Igor Brejc

1
Hình minh họa là có thật, nhưng việc triển khai tôi sử dụng không sử dụng thủ tục cập nhật hiệp phương sai và do đó không tối ưu về mặt tính toán.
whuber

2
Biểu đồ cuối cùng làm cho câu trả lời này thậm chí còn tuyệt vời hơn
Ragi Yaser Burhum

2
Igor, tôi nên đề cập rằng hướng nhãn đi kèm miễn phí: nó được đưa ra bởi hướng của trục chính của hình elip (hàm riêng liên quan đến giá trị riêng lớn hơn). Do đó, bạn có thể đồng thời tìm kiếm một cách hiệu quả cho sự kết hợp tốt nhất của định hướng nhãn và tuyến tính của phần đường viền.
whuber

3

Trong cộng đồng đồ họa máy tính, thường cần tìm một hộp giới hạn xung quanh một đối tượng. Do đó, đó là một vấn đề được nghiên cứu kỹ lưỡng, với các thuật toán nhanh. Ví dụ, xem bài viết thuật toán hộp giới hạn tối thiểu của Wikipedia . Bạn có thể tìm thấy hình chữ nhật có diện tích tối thiểu xung quanh đa tuyến của mình, sau đó sử dụng tỷ lệ khung hình, chiều cao / chiều dài của hình chữ nhật. Để có được số đo chính xác hơn, bạn có thể nhìn vào độ lệch của đa tuyến so với đường tâm của hình chữ nhật giới hạn này.


1
Tôi đã nghĩ về việc sử dụng min. Các hộp giới hạn, nhưng tôi thấy có hai vấn đề: a) độ phức tạp tính toán của một hộp thực sự sẽ là tối thiểu (và do đó được quay), b) hai đoạn đường cong có cùng tỷ lệ khung hình có thể có độ cong rất khác nhau (nghĩ về hình sin đường cong có cùng biên độ nhưng chu kỳ sóng khác nhau).
Igor Brejc

1
Thật vui khi thấy bạn ở đây trên các trang GIS, Joseph!
whuber

1
Vâng, tôi có cuốn sách "Hình học tính toán trong C" của bạn ngay bây giờ :)
Igor Brejc

1
Cảm ơn sự chào đón của mọi người! :-) Tôi nhận ra đề xuất của tôi không phải là biện pháp lý tưởng, nhưng mã hóa thì không có giá trị (nếu bạn có đúng giá). Loại vấn đề này đã được nghiên cứu khá nhiều trong bối cảnh sản xuất, trong đó họ cần đo chất lượng của một bộ phận gia công.
Joseph O'Rourke

3

Tôi không biết nếu điều này có ích, hoặc thậm chí nếu nó được coi là một câu trả lời, nhưng khi tôi ngồi đây suy nghĩ về câu hỏi tôi vừa đăng, tôi có một suy nghĩ:

Điều gì sẽ xảy ra nếu bạn đặt một vòng tròn có bán kính cụ thể trên đường viền của bạn. Vòng tròn đó sẽ cắt đường đồng mức ở ít nhất hai nơi. Đường càng căng, khoảng cách dọc theo đường đồng mức giữa hai điểm giao nhau càng ngắn. Khoảng cách dọc theo đường đồng mức giữa các điểm giao nhau càng dài thì đường cong càng cong. Nếu có nhiều hơn hai điểm giao nhau, đường đồng mức quá cong.

Bạn có thể tìm ra chiều dài nào sẽ đưa ra chỉ số về độ thẳng tốt nhất và thiết lập thói quen để đi dọc theo từng đường viền và nơi đủ thẳng, đặt nhãn.

Tôi chắc chắn rằng điều này không giúp được gì nhiều, và những gì tôi nói bằng tiếng Anh khó hơn rất nhiều trong bất kỳ ngôn ngữ lập trình nào bạn đang sử dụng, nhưng nó có thể là một sự khởi đầu?


Ý tưởng thú vị. Để đơn giản hơn, bạn có thể tính tỷ lệ giữa độ dài của đoạn ở một bên và khoảng cách giữa điểm bắt đầu và điểm kết thúc. Nó không chính xác, nhưng nó nhanh chóng để tính toán. Và ý tưởng của bạn về việc sử dụng một vòng tròn sẽ cho phép tính toán chính xác hơn về độ thẳng.
Igor Brejc

3

Cách tiếp cận dễ nhất tôi có thể nghĩ đến là tỷ lệ giữa độ dài đường dẫn thực tế giữa điểm bắt đầu và điểm kết thúc và khoảng cách ngắn nhất (đường thẳng) từ điểm bắt đầu đến điểm kết thúc. Các đường thẳng sẽ có tỷ lệ gần bằng một trong khi các đường rất cong sẽ có tỷ lệ rất cao.

Đây phải là một giải pháp thực sự dễ dàng để thực hiện.


Cập nhật: Như Mike nhận thấy chính xác, điều này sẽ bằng Sinuosity .

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


Chỉ là những gì tôi nghĩ đến sau khi đọc câu trả lời của Rex :)
Igor Brejc

4
về cơ bản là sự đối ứng của tội lỗi
Mike T

chính xác :) ....
underdark

2
Bạn đúng rằng điều này sẽ dễ thực hiện, bởi vì việc cập nhật độ dài khi một tìm kiếm cho các phân đoạn phù hợp để gắn nhãn cũng đơn giản như việc cộng và trừ độ dài giữa các đỉnh liên tiếp. Tuy nhiên, tính ngoằn ngoèo không nắm bắt hiệu quả ý nghĩa trong đó một đường cong có thể khởi hành từ tuyến tính. Ví dụ, so sánh một hình bán nguyệt có đường kính 100 với một chuỗi hình bán nguyệt có đường kính 1 : cả hai đường cong có cùng độ uốn lượn, nhưng độ lệch từ bên này sang bên kia gấp 100 lần so với thứ hai (sẽ là cơ sở tốt cho một nhãn).
whuber

Hãy tính đến việc nếu đa tuyến của bạn vẽ một vòng tròn thì phương pháp này sẽ mang lại cho bạn một sự tội lỗi vô hạn mà có lẽ không phải là kết quả mong muốn.
obchardon

1

Bằng cách tìm kiếm "độ cong" và "đa tuyến", tôi đã nhận được thông tin này Làm thế nào tôi có thể tìm thấy độ cong của một đa tuyến? . Ở đó, ông đề nghị sử dụng quay trở lại định nghĩa về độ cong - K= DF/Ds. Ở đây Fcó nghĩa là anh ta phi, hoặc Ttrong ký hiệu của wikipedia ở đây ( http://en.wikipedia.org/wiki/Curvature ).

Giả sử bạn có một chuỗi ba điểm, p0, p1 và p2. tính khoảng cách sgiữa p0 và p1, là delta của s ( Ds), giả sử các điểm gần đủ với nhau. Sau đó, bạn cần delta của T ( DT), đó là thay đổi trong vectơ tiếp tuyến đơn vị giữa p0 và p1. có thể có cách tinh vi nhưng phương pháp thô mà tôi có thể nghĩ ra để lấy hai điểm p0-> p1, p1-> p2, chuẩn hóa mỗi điểm có độ dài bằng một, sau đó lấy phép trừ vector của hai điểm đó sau đó xác định độ lớn. Đó là DT. Bộ phận mang lại một độ cong K0_1. lấy p1, p2 và p3 để tính toán K1_2và cứ thế.

Mặc dù vậy, tôi tự hỏi nếu bạn có được đường viền dưới dạng đa tuyến chứ không phải là pixel được hiển thị. Bạn nói 100px vì vậy mà làm tôi lo lắng một chút.


Cảm ơn liên kết, tôi sẽ phải nghiên cứu các toán học đằng sau nó. Tôi đã đề cập 100px chỉ đơn giản vì văn bản nhãn được hiển thị có chiều rộng nhất định (tính bằng pixel), 100px chỉ là một ví dụ.
Igor Brejc

Suy nghĩ về độ cong là một ý tưởng tốt đẹp. Độ cong trên các phần đường viền được làm nhẵn có độ dài đủ có thể phù hợp, nhưng bản thân độ cong không phải là: một đường zig-zag nhỏ sẽ có độ cong cực cao, chẳng hạn, nhưng sẽ không quan trọng về tổng thể. Do đó, trong thực tế, bạn sẽ sử dụng một số tóm tắt thống kê về độ lệch so với tuyến tính trên các phần của đa tuyến. Trong số các ứng cử viên có khả năng, độ cong sẽ là một trong những tính toán phức tạp hơn để thực hiện.
whuber
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.