/tags/R2002-04-20/octave-forge/main/image/bwlabel.m
Objective C | 233 lines | 187 code | 46 blank | 0 comment | 35 complexity | 0415e0e62994c5554a883ef4bd339dec MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
- ## Copyright (C) 2000 Etienne Grossmann
- ##
- ## This program is free software; you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation; either version 2 of the License, or
- ## (at your option) any later version.
- ##
- ## This program is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
- ##
- ## You should have received a copy of the GNU General Public License
- ## along with this program; if not, write to the Free Software
- ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- ## [im2,npix,bb] = bwlabel(im,...)
- ##
- ## Find the connected regions of an image.
- ##
- ## im : RxC 0-1 matrix
- ##
- ## im2 : RxC int matrix in which the connected regions of im have been
- ## numbered. 4-neighborhoods are considered.
- ##
- ## npix : 1xQ int number of pixel in each region
- ##
- ## bb : 4xQ int bounding boxes of the regions. Rows are minrow,
- ## maxrow, mincol, maxcol.
- ##
- ## Since the algorithm is slow, it will report progress if it has to do
- ## more than 100 loops.
- ##
- ## Options :
- ##
- ## "verbose" : Be verbose
- ## "quiet" : Don't report anything (overrides "verbose")
- ## "prudent" : Check that regions do not touch
- ## "mins", m : Minimum size of the regions
- ## "maxs", m : Maximum size of the regions
- ##
- ## Author: Etienne Grossmann <etienne@isr.ist.utl.pt>
- ## Last modified: January 2000
- function [im2,npix,bb] = bwlabel(im,...)
- [R,C]=size(im);
- tr = 0 ;
- # Loop as little as possible
- if R<C, tr = 1; im = im' ; [R,C]=size(im); end
- report = C>100 ;
- quiet = 0 ;
- verbose = 0 ;
- prudent = 1 ;
- mins = maxs = 0 ;
- filename = "bwlabel" ;
- opt0 = " verbose quiet " ;
- opt1 = " mins maxs " ;
- nargin-- ;
- read_options ;
- if any(im(:)&im(:)!=1),
- printf("bwlabel : im is not binary\n");
- return
- end
- if quiet, verbose = report = 0 ; end
- gsize = 100 ; # Predicted number of slices
- im2 = zeros(R,C);
- ## keyboard
- # find horizontal up/down going edges
- imup = max(im2, diff([zeros(1,C);im])) ;
- imdo = -min(im2, diff([im;zeros(1,C)])) ;
- im2 = ones(R,C);
- ######################################################################
- ## Find connected regions ############################################
- rc = 1 ; # Counter of region slices
- rnum = ones(1,gsize); # List of labels of each slice
- npix = zeros(1,gsize); # Sizes of regions (actual size is in
- # region's first slice)
- bb = zeros(4,gsize); # Bounding boxes
- if report && !verbose,
- printf("bwlabel : There will be %i loops ... \n%5i ",C,0) ;
- end
- lrow = zeros(R,1); # Last treated image column
-
- for i=1:C,
- ## i
- t1 = find(imup(:,i)) ;
- t2 = find(imdo(:,i)) ;
-
- nrow = zeros(R,1); # Next row
- ## if i==42 || i==41,"i==42 || i==41", keyboard; end
- for j = 1:rows(t1(:)) , # Loop over slices of i'th column
- rc++ ; # rc = number of current slice.
- im2(t1(j):t2(j),i) = rc ;
- ## if rc==341, "rc==341",keyboard; end
- # Slices from previous column that touch
- # this slice.
- rr = create_set(lrow(t1(j):t2(j))) ;
- if !isempty(rr) && !rr(1), rr = rr(2:length(rr)) ; end
- if rc>size(rnum,2), # Get more space (uncertain effect on
- # speed; avoids resizing rnum and npix)
- tmp = 2*(ceil(C*rc/i)-rc+1+rows(t1(:))-j) ;
- sayif(verbose,"bwlabel : (i=%i) Foreseeing %i more regions\n",i,tmp);
- rnum = [ rnum, ones(1,tmp) ] ;
- npix = [ npix,zeros(1,tmp) ] ;
- bb = [ bb,zeros(4,tmp) ] ;
- end
- if isempty(rr), # New region
- sayif(verbose,"bwlabel : creating region %i\n",rc);
- r0 = rc ; # r0 = number of the region
- bb(1,r0) = t1(j) ;
- bb(2,r0) = t2(j) ;
- bb(3:4,r0) = i ;
- else # Add to already existing region #####
- ## rr
- r0 = rnum(rr(1)) ;
- bb(1,r0) = min(bb(1,r0),t1(j)) ;
- bb(2,r0) = max(bb(2,r0),t2(j)) ;
- bb(4,r0) = i ;
- # Touches region r0
- sayif(verbose,"bwlabel : adding to region %i\n",r0);
- # Touches other regions too
- for k = rr(find(rr!=r0)), # Loop over other touching regions, that
- # should be merged to the first.
- sayif(verbose,"bwlabel : merging regions %i and %i\n",k,r0);
- rnum(find(rnum==k)) = r0 ;
- npix(r0) = npix(r0) + npix(k) ;
- bb([1,3],r0) = min(bb([1,3],r0)',bb([1,3],k)')' ;
- bb([2,4],r0) = max(bb([2,4],r0)',bb([2,4],k)')' ;
- end
-
- end # End of add to already existing region
- ## if r0==259 && i==39,"r0==259",keyboard;end
- rnum(rc) = r0 ;
- npix(r0) = npix(r0) + 1+t2(j)-t1(j) ;
- nrow(t1(j):t2(j)) = r0 ;
- end # End of looping over slices
- lrow = nrow ;
- if report && !verbose,
- printf(".") ;
- if !rem(i,70) && i<C, printf("\n%5i ",i); end
- end
- end # End of looping over columns
- ## length(regs)
- if report && !verbose,
- printf("\n") ;
- end
- ## im2
- ## [ 1:rc ; rnum(1:rc) ]
- keep = ones(1,rc) ;
- if mins, keep = keep & (npix(rnum(1:rc))>=mins) ; end
- if maxs, keep = keep & (npix(rnum(1:rc))<=maxs) ; end
- keep(1) = 1 ;
- keep = find(keep) ; # Indices of slices to be kept
- foo = create_set(rnum(keep)) ; # Indices of regions to be kept
- nr = prod(size(foo)) ; # Number of regions (including bg)
- ## lrow = zeros(1,nr) ;
- tmp = zeros(1,rc) ;
- tmp(foo) = 0:nr-1 ;
- bar = zeros(1,rc) ;
- bar(keep) = tmp(rnum(keep)) ;
- ## keyboard
- im2 = reshape(bar(im2),R,C) ;
- npix = npix(foo(2:nr));
- bb = bb(:,foo(2:nr));
- if 0, # Draw bb on the image (will ruin
- # coherence)
- for i=1:nr-1,
- im2([bb(1,i),bb(2,i)] ,bb(3,i):bb(4,i) ) = i ;
- im2( bb(1,i):bb(2,i) ,[bb(3,i),bb(4,i)]) = i ;
- end
- end
- ## keyboard
- if prudent,
- sayif(verbose,"bwlabel : Checking coherence\n");
- hcontact = im2 & im2!=[im2(:,2:C),zeros(R,1)] & [im2(:,2:C),zeros(R,1)] ;
- vcontact = im2 & im2!=[im2(2:R,:);zeros(1,C)] & [im2(2:R,:);zeros(1,C)] ;
- ok = 1 ;
- if any(hcontact(:)),
- ok = 0 ;
- printf("bwlabel: Whoa! Found horizontally connected separated regions\n");
- end
- if any(vcontact(:)),
- ok = 0 ;
- printf("bwlabel: Whoa! Found vertically connected separated regions\n");
- end
- if !ok, keyboard ; end
- end
- ## Eventually transpose result
- if tr,
- im2 = im2' ;
- bb = bb([3,4,1,2],:);
- end