Code covered by the BSD License  

Highlights from
Active Shape Model (ASM) and Active Appearance Model (AAM)

image thumbnail

Active Shape Model (ASM) and Active Appearance Model (AAM)

by

Dirk-Jan Kroon (view profile)

 

16 Feb 2010 (Updated )

Cootes 2D/3D Active Shape & Appearance Model for automatic image object segmentation and recognition

[uv xy]=PreProcessCp2tform(uv,xy)
function [uv xy]=PreProcessCp2tform(uv,xy)
% When CP2TFORM is used in piecewise linear mode, it uses triangulation
% to calculate the local image transformation. Sometimes a good 
% triangulation of basepoints gives folded triangles when used
% with the input points. The function CP2TFORM try's to remove 
% the controlpoints causing the folding, but often fails with the error:
%    Eliminated * control point pair(s).
%    Fold-over triangles remain. See CP2TFORM reference page.
%
% This function PreProcessCp2tform removes all control points which cause
% fold-over triangles with cp2tform. 
%
% [input_points,base_points]=PreProcessCp2tform(input_points,base_points);
%
% Function is written by D.Kroon University of Twente (March 2010)

% See if there are triangles after triangulation, which are upside down
tri = delaunay(xy(:,1),xy(:,2));
fold_triangles = FindUpsideDown(xy,uv,tri);

while(~isempty(fold_triangles))
    % Find the vertices in the fold-over triangle list which have the
    % largest angle, most probably causing the folding.
    tri_fold=tri(fold_triangles,:); tri_foldt=tri_fold';
    
    % Convert the folded triangle list, to list of vertex coordinates
    x = xy(:,1); y = xy(:,2);
    vx = reshape(x(tri_fold),size(tri_fold,1),3);
    vy = reshape(y(tri_fold),size(tri_fold,1),3);
    
    % Find the vertices with the largest angle in there triangles
    angle=[abs(dot([vx(:,1)-vx(:,3) vy(:,1)-vy(:,3)]',[vx(:,1)-vx(:,2) vy(:,1)-vy(:,2)]')) 
           abs(dot([vx(:,2)-vx(:,3) vy(:,2)-vy(:,3)]',[vx(:,2)-vx(:,1) vy(:,2)-vy(:,1)]')) 
           abs(dot([vx(:,3)-vx(:,1) vy(:,3)-vy(:,1)]',[vx(:,3)-vx(:,2) vy(:,3)-vy(:,2)]'))];
    [dum index] = min(angle); 
    bad_vertices=tri_foldt(index+(0:length(fold_triangles)-1)*3);
  
    % eliminate vertices causing folding
    bad_vertices = unique(bad_vertices);
    xy(bad_vertices,:) = []; uv(bad_vertices,:) = [];

    % See if there are triangles after triangulation, which are upside down
    tri = delaunay(xy(:,1),xy(:,2));
    fold_triangles = FindUpsideDown(xy,uv,tri);
end

function index = FindUpsideDown(xy,uv,tri)
% look for triangles which are upside down 
x = xy(:,1); y = xy(:,2);
u = uv(:,1); v = uv(:,2);

xx = reshape(x(tri),size(tri,1),3);
yy = reshape(y(tri),size(tri,1),3);
uu = reshape(u(tri),size(tri,1),3);
vv = reshape(v(tri),size(tri,1),3);

% Calculate the normal of the polygon
normalxy=cross([xx(:,2)-xx(:,1) yy(:,2)-yy(:,1) zeros(size(xx,1),1)],[xx(:,3)-xx(:,1) yy(:,3)-yy(:,1) zeros(size(xx,1),1)]);
normaluv=cross([uu(:,2)-uu(:,1) vv(:,2)-vv(:,1) zeros(size(xx,1),1)],[uu(:,3)-uu(:,1) vv(:,3)-vv(:,1) zeros(size(xx,1),1)]);

% Find the vertices with normals pointing in different directions
index = find(normalxy(:,3).*normaluv(:,3)<0);

Contact us