Solution undefined and 'double' type of input parameters matlab boundaries and fchcode can not perform the function corresponding to the function of 'boundaries'

When testing the code found matlab can not perform their function Freeman chain code:

fchcode boundaries and functions are working properly:

We need to add the following function in your working directory:

boundaries   fchcode     minmag     codediff

code show as below:


function B=boundaries(BW,conn,dir) 

%BOUNDARIES Trace object boundaries.

%B=BOUNDARIES(BW) traces the exterior boundaries of objects in the binary

%image BW.B is a p_by_1 cell array,where p is the number of objects in the

%image.Each cell contains a Q_by_2 matrix,each row of which contains the

%row and column coordinates of a boundary pixel.Q is the number of boundary

%pixels for the corresponding object.Object boundaries are traced in the

%clockwise direction.

%

%B=BOUNDARIES(BW,CONN) specifies the connectivity to use when tracing 

%boundaries.CONN may be either 8 or 4.The default value for CONN is 8.

%

%B=BOUNDARIES(BW,CONN,DIR) specifies the direction used for tracing 

%boundaries.DIR should be either 'cw'(trace boundaries clockwise) or 

%'ccw'(trace boundaries counterclockwise).If DIR is omitted BOUNDARIES

%traces in the clockwise direction.

if nargin <3% nargin defined user-defined functions in vivo, nargin return

              % Is used to call the function of the number of variables.

    dir = 'cw';

end

if nargin<2

    conn=8;

end

L = bwlabel (BW, conn);% The return value is a matrix L, with the size BW, comprising a portion of the tag communication in BW

%The number of objects is the maximum value of L.Initialize the cell

%array(元包数组)B so that each cell initially contains a 0_by_2 matrix.

numObjects = max (L (:));% Find the maximum value of L made in the tag, the maximum value actually corresponds to the L

% Up to the number of communication portions included.

if numObjects>0

    B = {zeros (0,2)};% element array package contains only one element.

    B = repmat (B, numObjects, 1);% B will be numObjects * 1 replication new configuration B.

else

    B={};

end

%Pad label matrix with zeros.This lets us write the boundary_following loop

%without worrying about going off the edge of the image.

Lp=padarray(L,[1 1],0,'both');

%Compute the linear indexing offsets to take us from a pixel to its

%neighbors.

M=size(Lp,1);%SIZE(X,1) returns the number of rows. 

if conn==8

    % Order is N NE E SE S SW W NW.

    offsets=[-1,M-1,M,M+1,1,-M+1,-M,-M-1];

else

    %Order is N E S W.

    offsets=[-1,M,1,-M];

end

%next_search_direction_lut is a lookup table.Given the direction from pixel

%k to pixel k+1,what is the direction to start with when examining the

%neighborhood of pixel k+1?

if conn==8

    next_search_direction_lut=[8 8 2 2 4 4 6 6];

else

    next_search_direction_lut=[4 1 2 3];

end

%next_direction_lut is a lookup table.Given that we just looked at neighbor

%in a given direction,which neighbor do we look at next?

if conn==8

  next_direction_lut=[2 3 4 5 6 7 8 1];

else

  next_direction_lut=[2 3 4 1];

end

%Values used for marking the starting and boundary pixels.

START=-1;

BOUNDARY=-2;

%Initialize scratch space in which to record the boundary pixels as well as

%follow the boundary.

scratch=zeros(100,1);

%Find candidate starting locations for boundaries.

[rr,cc]=find((Lp(2:end-1,:)>0)&(Lp(1:end-2,:)==0));

rr=rr+1;

for k=1:length(rr)

    r=rr(k);

    c=cc(k);

    if (Lp(r,c)>0)&(Lp(r-1,c)==0)&isempty(B{Lp(r,c)})

        %We've found the start of the next boundary.Compute its linear

        %offset,record which boundary it is,mark it,and initialize the

        %counter for the number of boundary pixels.

        idx=(c-1)*size(Lp,1)+r;

        which=Lp(idx);

        scratch(1)=idx;

        Lp(idx)=START;

        numpixels = 1;

        currentpixel=idx;

        initial_departure_direction=[];

        done=0;

        next_search_direction=2;

        while ~done

            %Find the next boundary pixel.

            direction=next_search_direction;

            found_next_pixel=0;

            for k=1:length(offsets)

                neighbor=currentpixel+offsets(direction);

                if Lp(neighbor)~=0

                    %Found the next boundary pixel.

                    if (Lp(currentpixel)==START)&...

                        isempty(initial_departure_direction)

                    %We are making the initial departure from the starting

                    %pixel.

                    initial_departure_direction=direction;

                    elseif (Lp(currentpixel)==START)&...

                            (initial_departure_direction==direction)

                      % We are about to retrace our path.

                      %That means we're done.

                      done=1;

                      found_next_pixel=1;

                      break;

                    end

                    %Take the next step along the boundary.

                    next_search_direction=...

                        next_search_direction_lut(direction);

                    found_next_pixel=1;

                    numpixels numpixels + = 1;

                    if numpixels>size(scratch,1)

                        %Double the scratch space.

                        scratch(2*size(scratch,1))=0;

                    end

                    scratch(numpixels)=neighbor;

                    if Lp(neighbor)~=START

                      Lp(neighbor)=BOUNDARY;

                    end

                    currentpixel=neighbor;

                    break;

                end

                direction=next_direction_lut(direction);

            end

            if ~found_next_pixel

                %If there is no next neighbor,the object must just have a

                %single pixel.

                numpixels = 2;

                scratch(2)=scratch(1);

                done=1;

            end

        end

        %Convert linear indices to row_column coordinates and save in the

        %output cell array.

        [row,col]=ind2sub(size(Lp),scratch(1:numpixels));

        B{which}=[row-1,col-1];

    end

end

if strcmp(dir,'ccw')

    for k=1:length(B)

        B{k}=B{k}(end:-1:1,:);

    end

end



function c = fchcode(b, conn, dir)

%FCHCODE Computes the Freeman chain code of a boundary.

%  C = FCHCODE(B) computes the 8-connected Freeman chain code of a

%  set of 2-D coordinate pairs contained in B, an np-by-2 array. C

%  is a structure with the following fields:

%

%    c.fcc    = Freeman chain code (1-by-np)

%    c.diff  = First difference of code c.fcc (1-by-np)

%    c.mm    = Integer of minimum magnitude from c.fcc (1-by-np)

%    c.diffmm = First difference of code c.mm (1-by-np)

%    c.x0y0  = Coordinates where the code starts (1-by-2)

%

%  C = FCHCODE(B, CONN) produces the same outputs as above, but

%  with the code connectivity specified in CONN. CONN can be 8 for

%  an 8-connected chain code, or CONN can be 4 for a 4-connected

%  chain code. Specifying CONN=4 is valid only if the input

%  sequence, B, contains transitions with values 0, 2, 4, and 6,

%  exclusively.

%     

%  C = FHCODE(B, CONN, DIR) produces the same outputs as above, but,

%  in addition, the desired code direction is specified. Values for

%  DIR can be:

%

%    'same'      Same as the order of the sequence of points in b.

%                This is the default.

%

%    'reverse'  Outputs the code in the direction opposite to the

%                direction of the points in B.  The starting point

%                for each DIR is the same.

%

%  The elements of B are assumed to correspond to a 1-pixel-thick,

%  fully-connected, closed boundary. B cannot contain duplicate

%  coordinate pairs, except in the first and last positions, which

%  is a common feature of boundary tracing programs.

%  FREEMAN CHAIN CODE REPRESENTATION

%  The table on the left shows the 8-connected Freeman chain codes

%  corresponding to allowed deltax, deltay pairs. An 8-chain is

%  converted to a 4-chain if (1) if conn = 4; and (2) only

%  transitions 0, 2, 4, and 6 occur in the 8-code.  Note that

%  dividing 0, 2, 4, and 6 by 2 produce the 4-code.

%

%      -----------------------  ----------------

%      deltax | deltay | 8-code  corresp 4-code

%      -----------------------  ----------------

%        0        1      0            0

%        -1        1      1

%        -1        0      2            1

%        -1      -1      3

%        0      -1      4            2

%        1      -1      5

%        1        0      6            3

%        1        1      7

%      -----------------------  ----------------

%

%  The formula z = 4*(deltax + 2) + (deltay + 2) gives the following

%  sequence corresponding to rows 1-8 in the preceding table: z =

%  11,7,6,5,9,13,14,15. These values can be used as indices into the

%  table, improving the speed of computing the chain code. The

%  preceding formula is not unique, but it is based on the smallest

%  integers (4 and 2) that are powers of 2.

%  Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins

%  Digital Image Processing Using MATLAB, Prentice-Hall, 2004

%  $Revision: 1.6 $  $Date: 2003/11/21 14:34:49 $

% Preliminaries.

if nargin == 1

  dir = 'same';

  conn = 8;

elseif Nargin == 2

  dir = 'same';

elseif Nargin == 3 

  % Nothing to do here.

else

  error('Incorrect number of inputs.')

end

[np, nc] = size(b);

if np < nc

  error('B must be of size np-by-2.');

end

% Some boundary tracing programs, such as boundaries.m, output a

% sequence in which the coordinates of the first and last points are

% the same. If this is the case, eliminate the last point.

if isequal(b(1, :), b(np, :))

  np = np - 1;

  b = b (1: np :);

end

% Build the code table using the single indices from the formula

% for z given above:

C(11)=0; C(7)=1; C(6)=2; C(5)=3; C(9)=4;

C(13)=5; C(14)=6; C(15)=7;

% End of Preliminaries.

% Begin processing.

x0 = b(1, 1);

y0 = b(1, 2);

c.x0y0 = [x0, y0];

% Make sure the coordinates are organized sequentially:

% Get the deltax and deltay between successive points in b. The

% last row of a is the first row of b.

a = circshift(b, [-1, 0]);

% DEL = a - b is an nr-by-2 matrix in which the rows contain the

% deltax and deltay between successive points in b. The two

% components in the kth row of matrix DEL are deltax and deltay

% between point (xk, yk) and (xk+1, yk+1).  The last row of DEL

% contains the deltax and deltay between (xnr, ynr) and (x1, y1),

% (i.e., between the last and first points in b).

DEL = a - b;

% If the abs value of either (or both) components of a pair

% (deltax, deltay) is greater than 1, then by definition the curve

% is broken (or the points are out of order), and the program

% terminates.

if any(abs(DEL(:, 1)) > 1) | any(abs(DEL(:, 2)) > 1);

  error('The input curve is broken or points are out of order.')

end

% Create a single index vector using the formula described above.

z = 4 * (DEL (:, 1) + 2) + (DEL (:, 2) + 2);

% Use the index to map into the table. The following are

% the Freeman 8-chain codes, organized in a 1-by-np array.

fcc = C(z);

% Check if direction of code sequence needs to be reversed.

if strcmp(dir, 'reverse')

  fcc = coderev(fcc); % See below for function coderev.

end

% If 4-connectivity is specified, check that all components

% of fcc are 0, 2, 4, or 6.

if conn == 4

  val = find(fcc == 1 | fcc == 3 | fcc == 5 | fcc ==7 );

  if isempty(val)

      fcc = fcc./2;

  else

      warning('The specified 4-connected code cannot be satisfied.')

  end

end

% Freeman chain code for structure output.

c.fcc = fcc;

% Obtain the first difference of fcc.

c.diff = codediff(fcc,conn); % See below for function codediff.

% Obtain code of the integer of minimum magnitude.

c.mm = minmag(fcc); % See below for function minmag.

% Obtain the first difference of fcc

c.diffmm = codediff(c.mm, conn);



function z = minmag(c)

%MINMAG Finds the integer of minimum magnitude in a chain code.

%  Z = MINMAG(C) finds the integer of minimum magnitude in a given

%  4- or 8-connected Freeman chain code, C. The code is assumed to

%  be a 1-by-np array.

% The integer of minimum magnitude starts with min(c), but there

% may be more than one such value. Find them all,

I = find (c == min (c));

% and shift each one left so that it starts with min(c).

J = 0;

A = zeros(length(I), length(c));

for k = I;

  J = J + 1;

  A(J, :) = circshift(c,[0 -(k-1)]);

end

% Matrix A contains all the possible candidates for the integer of

% minimum magnitude. Starting with the 2nd column, succesively find

% the minima in each column of A. The number of candidates decreases

% as the seach moves to the right on A.  This is reflected in the

% elements of J.  When length(J)=1, one candidate remains.  This is

% the integer of minimum magnitude. 

[M, N] = size(A);

J = (1:M)';

for k = 2:N

  D(1:M, 1) = Inf;

  D(J, 1) = A(J, k);

  = min (A (J, k));

  J = find(D(:, 1) == amin);

  if length(J)==1

      z = A(J, :);

      return

  end

end



function d = codediff(fcc, conn)

%CODEDIFF Computes the first difference of a chain code.

%  D = CODEDIFF(FCC) computes the first difference of code, FCC. The

%  code FCC is treated as a circular sequence, so the last element

%  of D is the difference between the last and first elements of

%  FCC.  The input code is a 1-by-np vector.

%

%  The first difference is found by counting the number of direction

%  changes (in a counter-clockwise direction) that separate two

%  adjacent elements of the code.

sr = circshift(fcc, [0, -1]); % Shift input left by 1 location.

delta = sr - fcc;

d = delta;

I = find(delta < 0);

type = conn;

switch type

case 4 % Code is 4-connected

  d(I) = d(I) + 4;

case 8 % Code is 8-connected

  d(I) = d(I) + 8;

end


After adding more functions, test code can run smoothly:

close all;clear all;clc;

I = [1 1 1 1;1 1 0 1;0 1 0 1;0 1 1 1];

g = boundaries (I, 4);% target track boundary 4 is connected

c = fchcode (g {:}, 4);% seek direction freeman chain code 4

c

output:

c = 

      x0y0: [1 1]% c.x0y0 display coordinates at the beginning of the code (1 × 2)

      fcc: [0 0 0 3 3 3 2 2 1 1 2 1]% c.fcc Freeman chain code represents (1 × n), the boundary point set of size (n × 2)

      diff: [0 0 3 0 0 3 0 3 0 1 3 3] first difference codes c.fcc% c.diff the (1 × n)

        mm: [0 0 0 3 3 3 2 2 1 1 2 1]% c.mm represents an integer of minimum amplitude

    diffmm: [0 0 3 0 0 3 0 3 0 1 3 3]% c.diffmm order difference represents a (1 × n) of the code c.mm

Guess you like

Origin www.cnblogs.com/wojianxin/p/11440274.html