⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edgelink.m

📁 hopfield neural network for binary image recognition
💻 M
字号:
% EDGELINK - Link edge points in an image into lists%% Usage: [edgelist edgeim] = edgelink(im, minlength, location)%% Arguments:  im         - Binary edge image, it is assumed that edges%                          have been thinned.%             minlength  - Optional minimum edge length of interest, defaults%                          to 1 if omitted or specified as [].%             location   - Optional complex valued image holding subpixel%                          locations of edge points. For any pixel the%                          real part holds the subpixel row coordinate of%                          that edge point and the imaginary part holds%                          the column coordinate.  See NONMAXSUP.  If%                          this argument is supplied the edgelists will%                          be formed from the subpixel coordinates,%                          otherwise the the integer pixel coordinates of%                          points in 'im' are used.%% Returns:  edgelist - a cell array of edge lists in row,column coords in%                      the form%                     { [r1 c1   [r1 c1   etc }%                        r2 c2    ...%                        ...%                        rN cN]   ....]   %%           edgeim   - Image with pixels labeled with edge number. Note that%                      this image also includes edges that do not meet the%                      minimum length specification.  If you want to see just%                      the edges that meet the specification you should pass%                      the edgelist to DRAWEDGELIST.%%% This function links edge points together into lists of coordinate pairs.% Where an edge junction is encountered the list is terminated and a separate% list is generated for each of the branches.%% See also:  DRAWEDGELIST, LINESEG, MAXLINEDEV, CLEANEDGELIST, FINDENDSJUNCTIONS%% Bugs: This code has caused me much grief on and off.  I keep discovering cases% that do not get handled properly. The logic has grown in a way that is less% structured than I would like.  At the moment I am aware that if there are two% adjacent junction points things may go a bit astray.%% You may find a few edges that are needlessly broken into two, or more,% segements.  This should be fixed up by CLEANEDGELIST which gets called if% you specify a non-empty value for minlength.  Use a value of 0 if you want to% fix this without trimming small edges.%% It may be that you encounter problems in the call to CLEANEDGELIST (which% has perhaps caused me even more grief).  By calling edgelink with just the% image arguments, or with an empty value for minlength, CLEANEDGELIST will% not be called, and you will be spared any errors there.% Acknowledgement:% Some of this code is inspired by David Lowe's Link.c function from the% Vista image processing library developed at the University of British% Columbia %    http://www.cs.ubc.ca/nest/lci/vista/vista.html% Copyright (c) 2001-2007 Peter Kovesi% School of Computer Science & Software Engineering% The University of Western Australia% http://www.csse.uwa.edu.au/% % Permission is hereby granted, free of charge, to any person obtaining a copy% of this software and associated documentation files (the "Software"), to deal% in the Software without restriction, subject to the following conditions:% % The above copyright notice and this permission notice shall be included in % all copies or substantial portions of the Software.%% The Software is provided "as is", without warranty of any kind.% February  2001 - Original version% September 2004 - Revised to allow subpixel edge data to be used% November  2006 - Changed so that edgelists start and stop at every junction % January   2007 - Prefiltering to to discard isolated pixels and the%                  problems they cause(thanks to Jeff Copeland)% January   2007 - Fixes to ensure closed loops are closed, and a few other%                  cases are handled betterfunction [edgelist, edgeim] = edgelink(im, minlength, location)        global EDGEIM;      % Some global variables to avoid passing (and                        % copying) of arguments, this improves speed.    global ROWS;    global COLS;    global RJ;    global CJ;        EDGEIM = im ~= 0;                     % make sure image is binary.    EDGEIM = bwmorph(EDGEIM,'clean');     % Remove isolated pixels    EDGEIM = bwmorph(EDGEIM,'skel',Inf);  % and make sure edges are thinned. I                                          % think using 'skel' is better than 'thin'            % Find endings and junctions in edge data    [RJ, CJ, re, ce] = findendsjunctions(EDGEIM);    EDGEIM = double(EDGEIM);   % Convert to double to allow the use of -ve labelings    [ROWS, COLS] = size(EDGEIM);    edgeNo = 0;            % Perform raster scan through image looking for edge points.  When a    % point is found trackedge is called to find the rest of the edge    % points.  As it finds the points the edge image pixels are labeled    % with the -ve of their edge No        for r = 1:ROWS	for c = 1:COLS	    if EDGEIM(r,c) == 1		edgepoints = trackedge(r,c, edgeNo);		if ~isempty(edgepoints)		    edgeNo = edgeNo + 1;		    		    edgelist{edgeNo} = edgepoints;		end	    end	end    end        edgeim = -EDGEIM;  % Finally negate image to make edge encodings +ve.        % Eliminate isolated edges and spurs that are below the minimum length    if nargin >= 2 && ~isempty(minlength)	edgelist = cleanedgelist(edgelist, minlength);        else  % Call cleanedgelist with 0 minlength anyway to fix spurrious nodes          % that may exist due to problem with EDGELINK at points where          % junctions are adjacent.	edgelist = cleanedgelist(edgelist, 0);    end           % If subpixel edge locations are supplied upgrade the integer precision    % edgelists that were constructed with data from 'location'.    if nargin == 3	for I = 1:length(edgelist)	    ind = sub2ind(size(im),edgelist{I}(:,1),edgelist{I}(:,2));	    edgelist{I}(:,1) = real(location(ind))';	    edgelist{I}(:,2) = imag(location(ind))';    	end    end        %----------------------------------------------------------------------    % TRACKEDGE%% Function to track all the edge points associated with a start point.  From a% given starting point it tracks in one direction, storing the coords of the% edge points in an array and labelling the pixels in the edge image with the% -ve of their edge number. This continues until no more connected points are% found, or a junction point is encountered.  At this point the function returns% to the start point and tracks in the opposite direction.%% Usage:   edgepoints = trackedge(rstart, cstart, edgeNo)% % Arguments:   rstart, cstart   - row and column No of starting point%              edgeNo           - the current edge number%              minlength        - minimum length of edge to accept%% Returns:     edgepoints       - Nx2 array of row and col values for%                                 each edge point.function edgepoints = trackedge(rstart, cstart, edgeNo)        global EDGEIM;    global RJ;    global CJ;    global noPoint;    global thereIsAPoint;    global lastPoint;        noPoint = 0;    thereIsAPoint = 1;    lastPoint = 2;        edgepoints = [rstart cstart];      % Start a new list for this edge.    EDGEIM(rstart,cstart) = -edgeNo;   % Edge points in the image are 			               % encoded by -ve of their edgeNo.        [status, r, c] = nextpoint(rstart,cstart, edgeNo); % Find next connected                                                       % edge point.    while status ~= noPoint	edgepoints = [edgepoints             % Add point to point list  	     	       r    c   ];	EDGEIM(r,c) = -edgeNo;               % Update edge image	if status == lastPoint               % We have hit a junction point	    status = noPoint;                % make sure we stop tracking here	else	    [status, r, c] = nextpoint(r,c, edgeNo); % Otherwise keep going	end    end    % Now track from original point in the opposite direction - but only if    % the starting point was not a junction point        if ~isjunction(rstart,cstart)        	% First reverse order of existing points in the edge list	edgepoints = flipud(edgepoints);  		% ...and start adding points in the other direction.	[status, r, c] = nextpoint(rstart,cstart, edgeNo); 		while status ~= noPoint	    edgepoints = [edgepoints			  r    c   ];	    EDGEIM(r,c) = -edgeNo;	    if status == lastPoint		status = noPoint;	    else		[status, r, c] = nextpoint(r,c, edgeNo);	    end	end    end        % Final check to see if this edgelist should have start and end points    % matched to form a loop.  If the number of points in the list is four or    % more (the minimum number that could form a loop), and the endpoints are    % within a pixel of each other, append a copy if the first point to the    % end to complete the loop        if length(edgepoints) >= 4	if abs(edgepoints(1,1) - edgepoints(end,1)) <= 1  &&  ...           abs(edgepoints(1,2) - edgepoints(end,2)) <= 1 	    edgepoints = [edgepoints			  edgepoints(1,:)];	end    end            %----------------------------------------------------------------------    %% NEXTPOINT%% Function finds a point that is 8 connected to an existing edge point%function [status, nextr, nextc] = nextpoint(rp,cp, edgeNo)    global EDGEIM;    global ROWS;    global COLS;    global RJ;    global CJ;    global noPoint;    global thereIsAPoint;    global lastPoint;                % row and column offsets for the eight neighbours of a point    roff = [-1  0  1  0 -1 -1  1  1];    coff = [ 0  1  0 -1 -1  1  1 -1];    r = rp+roff;    c = cp+coff;        % Find indices of arrays of r and c that are within the image bounds    ind = find((r>=1 & r<=ROWS) & (c>=1 & c<=COLS));        % Search through neighbours and see if one is a junction point    for i = ind 	if (any(c(i) == CJ(RJ==r(i)))) && (EDGEIM(r(i),c(i)) ~= -edgeNo) 	    % This is a junction point that we have not marked as part of	    % this edgelist	    nextr = r(i);	    nextc = c(i);	    status = lastPoint;	    return;             % break out and return with the data	end    end        % If we get here there were no junction points.  Search through neighbours    % and return first connected edge point that itself has less than two    % neighbours connected back to our current edge.  This prevents occasional    % erroneous doubling back onto the wrong segment    checkFlag = 0;    for i = ind	if EDGEIM(r(i),c(i)) == 1	    n = neighbours(r(i),c(i));	    if sum(n==-edgeNo) < 2		nextr = r(i);		nextc = c(i);		status = thereIsAPoint;		return;             % break out and return with the data	    	    else                    % Remember this point just in case we		checkFlag = 1;      % have to use it		rememberr = r(i);		rememberc = c(i);			    end	    	end    end        % If we get here (and 'checkFlag' is true) there was no connected edge point    % that had less than two connections to our current edge, but there was one    % with more.  Use the point we remembered above.    if checkFlag      	nextr = rememberr;	nextc = rememberc;	status = thereIsAPoint;       	return;                % Break out    end            % If we get here there was no connecting next point at all.    nextr = 0;       nextc = 0;    status = noPoint;    %------------------------------------------------------------------------% Function to test whether a location in the image is a junction point.% Note that for speed this code has been hard wired into NEXTPOINT.function b = isjunction(r,c)    global RJ;    global CJ;        b = any(c == CJ(RJ==r));    %------------------------------------------------------------------------% Function to get the values of the 8 neighbouring pixels surrounding a point% of interest.  The values are ordered from the top-left point going% anti-clockwise around the pixel.function n = neighbours(rp, cp)        global EDGEIM;    global ROWS;    global COLS;    % row and column offsets for the eight neighbours of a point    roff = [-1  0  1  1  1  0 -1 -1];    coff = [-1 -1 -1  0  1  1  1  0];        r = rp+roff;    c = cp+coff;        % Find indices of arrays of r and c that are within the image bounds    ind = find((r>=1 & r<=ROWS) & (c>=1 & c<=COLS));        n = zeros(1,8);    for i = ind	n(i) = EDGEIM(r(i),c(i));        end    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -