• matlab boundaries和fchcode函数无法执行的解决办法 未定义与 'double' 类型的输入参数相对应的函数 'boundaries'


    在测试代码时发现,自己的matlab无法执行Freeman链码函数:

    boundaries和fchcode函数都无法正常运行:

    需要在自己的工作目录中添加如下函数:

    boundaries   fchcode     minmag     codediff

    代码如下:


    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定义在用户自定义函数体内,nargin返回

                  %用来调用函数的变量的个数。

        dir='cw';

    end

    if nargin<2

        conn=8;

    end

    L=bwlabel(BW,conn); %返回值是矩阵L,大小同BW,包含了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(:));%寻找L中所作标记中的最大值,这个最大值实际上就对应着L中

    % 包含的最多的连通部分的数目。

    if numObjects>0

        B={zeros(0,2)};%元包数组中仅包含一个元素。

        B=repmat(B,numObjects,1);%将B进行numObjects*1个复制构成新的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);

      amin = 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


    添加完以上函数后,测试代码可以顺利运行:

    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);  %追踪4连接目标边界

    c = fchcode(g{:},4);  %求4方向freeman链码

    c

    output:

    c = 

          x0y0: [1 1]  %c.x0y0显示代码开始处的坐标(1×2)

          fcc: [0 0 0 3 3 3 2 2 1 1 2 1]     %c.fcc表示Freeman链码(1×n),边界点集大小为 (n×2)

          diff: [0 0 3 0 0 3 0 3 0 1 3 3]      % c.diff 代码 c.fcc的一阶差分(1×n)

            mm: [0 0 0 3 3 3 2 2 1 1 2 1]   %c.mm表示最小幅度的整数

        diffmm: [0 0 3 0 0 3 0 3 0 1 3 3]   %c.diffmm表示代码c.mm的一阶差分(1×n)

  • 相关阅读:
    Emmet Documentation
    微软雅黑的Unicode码和英文名
    Eclipse让代码自动换行(WordWarp)
    如何更改MyEclipse代码自动换行的长度?
    PHP之道推荐使用PHP版本,数据库方式,以及虚拟机的创建程序
    ime-mode:disabled是什么?
    document.getElementsByClassName在ie8及其以下浏览器的兼容性问题
    Unobtrusive JavaScript 不唐突的JavaScript的七条准则
    详解 arguments, callee, caller, call, apply的区别
    怎样在谷歌浏览器上加载金山词霸的取词插件?
  • 原文地址:https://www.cnblogs.com/wojianxin/p/11440274.html
Copyright © 2020-2023  润新知