本文共 3589 字,大约阅读时间需要 11 分钟。
Fast Marching method 跟 dijkstra 方法类似,只不过dijkstra方法的路径只能沿网格,而Fast Marching method的方法可以沿斜线.
[Level Set Methods and Fast Marching Methods p94-95]
这里 u 理解为到达点的时间,
[Level Set Methods and Fast Marching Methods p7
]本例,首先加载一张灰度图片, 将里面像素的值W作为该点的流速F. 然后算到达该点的时间,也就是程序里面的距离D.
matlab部分源代码如下:
example1.mn = 400;[M,W] = load_potential_map('road2', n);%start_point = [16;219];%end_point = [394;192];% You can use instead the function[start_point,end_point] = pick_start_end_point(W);clear options;options.nb_iter_max = Inf;options.end_points = end_point; % stop propagation when end point reached[D,S] = perform_fast_marching(W, start_point, options);% nicde color for displayA = convert_distance_color(D);imageplot({W A}, { 'Potential map' 'Distance to starting point'}); colormap gray(256);
perform_front_propagation_2d_slow.m
function [D,S,father] = perform_front_propagation_2d_slow(W,start_points,end_points,nb_iter_max,H)% [D,S] = perform_front_propagation_2d_slow(W,start_points,end_points,nb_iter_max,H);%% [The mex function is perform_front_propagation_2d]%% 'D' is a 2D array containing the value of the distance function to seed.% 'S' is a 2D array containing the state of each point : % -1 : dead, distance have been computed.% 0 : open, distance is being computed but not set.% 1 : far, distance not already computed.% 'W' is the weight matrix (inverse of the speed).% 'start_points' is a 2 x num_start_points matrix where k is the number of starting points.% 'H' is an heuristic (distance that remains to goal). This is a 2D matrix.% % Copyright (c) 2004 Gabriel Peyr?data.D = W.*0 + Inf; % action 先把所有点的距离标为Infstart_ind = sub2ind(size(W), start_points(1,:), start_points(2,:));data.D( start_ind ) = 0; %将起点的距离设置为0data.O = start_points; % 将起点加入Open list % S=1 : far, S=0 : open, S=-1 : closedata.S = ones(size(W));% 将所点的状态设为Fardata.S( start_ind ) = 0; % 将起点的状态设为open(trial)data.W = W;data.father = zeros( [size(W),2] );% father维度400*400*2,父节点有两个,因为走斜线verbose = 1;if nargin<3 end_points = [];endif nargin<4 nb_iter_max = round( 1.2*size(W,1)^2 );endif nargin<5 data.H = W.*0;else if isempty(H) data.H = W.*0; else data.H = H; endendif ~isempty(end_points) end_ind = sub2ind(size(W), end_points(1,:), end_points(2,:));else end_ind = [];endstr = 'Performing Fast Marching algorithm.';if verbose h = waitbar(0,str);endi = 0; while i0 && jj>0 && ii<=n && jj<=p f = [0 0]; % current father %%% update the action using Upwind resolution P = h/W(ii,jj); % neighbors values a1 = Inf; if ii 1 && D( ii-1,jj ) 1 && D( ii,jj-1 ) a2 % swap to reorder tmp = a1; a1 = a2; a2 = tmp; f = f([2 1]); end % now the equation is (a-a1)^2+(a-a2)^2 = P^2, with a >= a2 >= a1. % 书上95页公式为:(ux^2 + uy^2)^(1/2)=1/Fijk % u理解为到达点的时间,Fijk理解为在点ijk处的流速 % 那么 ux = (a-a1)/(1/400), uy = (a-a2)/(1/400) % 所以方程变为:((a-a1)^2/(1/400))^2+((a-a2)^2/(1/400))^2 = (1/Wij)^2 % 把1/400移到右边,则得P if P^2 > (a2-a1)^2%delta 大于0 delta = 2*P^2-(a2-a1)^2; A1 = (a1+a2+sqrt(delta))/2; else%否则用dijkstra方法,沿着格子走,公式为:max|ux,uy|=1/Fijk % (a-a1) / (1/400) = 1 / Wij A1 = a1 + P; f(2) = 0;%将第2个父节点设为0 end switch S(ii,jj) case kClose%闭集不用更新 % check if action has change. Should not appen for FM if A1
运行结果: