Đây vẫn là một giải pháp thay thế cho vấn đề của bạn bằng cách mô hình hóa câu hỏi của bạn dưới dạng 'vấn đề tối ưu hóa đường dẫn'. Mặc dù nó phức tạp hơn so với giải pháp tạo đường cong đơn giản và sau đó là đường cong, nhưng nó mạnh mẽ hơn trong thực tế.
Từ mức rất cao, chúng ta nên xem hình ảnh này như một biểu đồ, trong đó
mỗi pixel hình ảnh là một nút trên biểu đồ này
mỗi nút được kết nối với một số nút khác, được gọi là hàng xóm và định nghĩa kết nối này thường được gọi là cấu trúc liên kết của biểu đồ này.
mỗi nút có trọng số (tính năng, chi phí, năng lượng hoặc bất cứ điều gì bạn muốn gọi nó), phản ánh khả năng nút này nằm trong một đường trung tâm tối ưu mà chúng tôi đang tìm kiếm.
Miễn là chúng ta có thể mô hình hóa khả năng này, thì vấn đề tìm kiếm 'đường trung tâm của rìa' sẽ trở thành vấn đề tìm đường dẫn tối ưu cục bộ trên biểu đồ , có thể giải quyết hiệu quả bằng lập trình động, ví dụ thuật toán Viterbi.
Dưới đây là một số ưu điểm của việc áp dụng phương pháp này:
tất cả các kết quả của bạn sẽ liên tục (không giống như phương pháp ngưỡng có thể chia một đường trung tâm thành từng mảnh)
rất nhiều quyền tự do để xây dựng một biểu đồ như vậy, bạn có thể chọn các tính năng khác nhau và cấu trúc liên kết biểu đồ.
kết quả của bạn là tối ưu theo nghĩa tối ưu hóa đường dẫn
giải pháp của bạn sẽ mạnh mẽ hơn chống lại nhiễu, vì miễn là nhiễu được phân bổ đều giữa tất cả các pixel, các đường dẫn tối ưu đó vẫn ổn định.
Dưới đây là một minh chứng ngắn về ý tưởng trên. Vì tôi không sử dụng bất kỳ kiến thức nào trước đó để chỉ định các nút bắt đầu và kết thúc có thể là gì, tôi chỉ cần giải mã wrt mỗi nút bắt đầu có thể.
Đối với các kết thúc mờ, nguyên nhân là do chúng ta đang tìm kiếm các đường dẫn tối ưu cho mọi nút kết thúc có thể. Kết quả là, mặc dù đối với một số nút nằm trong vùng tối, đường dẫn được tô sáng vẫn là đường dẫn tối ưu cục bộ.
Đối với đường dẫn mờ, bạn có thể làm mịn nó sau khi bạn tìm thấy nó hoặc sử dụng một số tính năng được làm mịn thay vì cường độ thô.
Có thể khôi phục các đường dẫn một phần bằng cách thay đổi các nút bắt đầu và kết thúc.
Sẽ không khó để cắt tỉa những con đường tối ưu cục bộ không mong muốn này. Bởi vì chúng tôi có khả năng của tất cả các đường dẫn sau khi giải mã viterbi và bạn có thể sử dụng nhiều kiến thức trước đó (ví dụ: chúng tôi thấy đúng là chúng tôi chỉ cần một đường dẫn tối ưu cho những người chia sẻ cùng một nguồn.)
Để biết thêm chi tiết, bạn có thể tham khảo bài báo.
Wu, Y.; Zha, S.; Cao, H.; Liu, D., & Natarajan, P. (2014, February). A Markov Chain Line Segmentation Method for Text Recognition. In IS&T/SPIE 26th Annual Symposium on Electronic Imaging (DRR), pp. 90210C-90210C.
Dưới đây là một đoạn mã python ngắn sử dụng để tạo biểu đồ trên.
import cv2
import numpy as np
from matplotlib import pyplot
# define your image path
image_path = ;
# read in an image
img = cv2.imread( image_path, 0 );
rgb = cv2.imread( image_path, -1 );
# some feature to reflect how likely a node is in an optimal path
img = cv2.equalizeHist( img ); # equalization
img = img - img.mean(); # substract DC
img_pmax = img.max(); # get brightest intensity
img_nmin = img.min(); # get darkest intensity
# express our preknowledge
img[ img > 0 ] *= +1.0 / img_pmax;
img[ img = 1 :
prev_idx = vt_path[ -1 ].astype('int');
vt_path.append( path_buffer[ prev_idx, time ] );
time -= 1;
vt_path.reverse();
vt_path = np.asarray( vt_path ).T;
# plot found optimal paths for every 7 of them
pyplot.imshow( rgb, 'jet' ),
for row in range( 0, h, 7 ) :
pyplot.hold(True), pyplot.plot( vt_path[row,:], c=np.random.rand(3,1), lw = 2 );
pyplot.xlim( ( 0, w ) );
pyplot.ylim( ( h, 0 ) );