PageRenderTime 47ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  1. ## Copyright (C) 2000 Etienne Grossmann
  2. ##
  3. ## This program is free software; you can redistribute it and/or modify
  4. ## it under the terms of the GNU General Public License as published by
  5. ## the Free Software Foundation; either version 2 of the License, or
  6. ## (at your option) any later version.
  7. ##
  8. ## This program is distributed in the hope that it will be useful,
  9. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ## GNU General Public License for more details.
  12. ##
  13. ## You should have received a copy of the GNU General Public License
  14. ## along with this program; if not, write to the Free Software
  15. ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. ## [im2,npix,bb] = bwlabel(im,...)
  17. ##
  18. ## Find the connected regions of an image.
  19. ##
  20. ## im : RxC 0-1 matrix
  21. ##
  22. ## im2 : RxC int matrix in which the connected regions of im have been
  23. ## numbered. 4-neighborhoods are considered.
  24. ##
  25. ## npix : 1xQ int number of pixel in each region
  26. ##
  27. ## bb : 4xQ int bounding boxes of the regions. Rows are minrow,
  28. ## maxrow, mincol, maxcol.
  29. ##
  30. ## Since the algorithm is slow, it will report progress if it has to do
  31. ## more than 100 loops.
  32. ##
  33. ## Options :
  34. ##
  35. ## "verbose" : Be verbose
  36. ## "quiet" : Don't report anything (overrides "verbose")
  37. ## "prudent" : Check that regions do not touch
  38. ## "mins", m : Minimum size of the regions
  39. ## "maxs", m : Maximum size of the regions
  40. ##
  41. ## Author: Etienne Grossmann <etienne@isr.ist.utl.pt>
  42. ## Last modified: January 2000
  43. function [im2,npix,bb] = bwlabel(im,...)
  44. [R,C]=size(im);
  45. tr = 0 ;
  46. # Loop as little as possible
  47. if R<C, tr = 1; im = im' ; [R,C]=size(im); end
  48. report = C>100 ;
  49. quiet = 0 ;
  50. verbose = 0 ;
  51. prudent = 1 ;
  52. mins = maxs = 0 ;
  53. filename = "bwlabel" ;
  54. opt0 = " verbose quiet " ;
  55. opt1 = " mins maxs " ;
  56. nargin-- ;
  57. read_options ;
  58. if any(im(:)&im(:)!=1),
  59. printf("bwlabel : im is not binary\n");
  60. return
  61. end
  62. if quiet, verbose = report = 0 ; end
  63. gsize = 100 ; # Predicted number of slices
  64. im2 = zeros(R,C);
  65. ## keyboard
  66. # find horizontal up/down going edges
  67. imup = max(im2, diff([zeros(1,C);im])) ;
  68. imdo = -min(im2, diff([im;zeros(1,C)])) ;
  69. im2 = ones(R,C);
  70. ######################################################################
  71. ## Find connected regions ############################################
  72. rc = 1 ; # Counter of region slices
  73. rnum = ones(1,gsize); # List of labels of each slice
  74. npix = zeros(1,gsize); # Sizes of regions (actual size is in
  75. # region's first slice)
  76. bb = zeros(4,gsize); # Bounding boxes
  77. if report && !verbose,
  78. printf("bwlabel : There will be %i loops ... \n%5i ",C,0) ;
  79. end
  80. lrow = zeros(R,1); # Last treated image column
  81. for i=1:C,
  82. ## i
  83. t1 = find(imup(:,i)) ;
  84. t2 = find(imdo(:,i)) ;
  85. nrow = zeros(R,1); # Next row
  86. ## if i==42 || i==41,"i==42 || i==41", keyboard; end
  87. for j = 1:rows(t1(:)) , # Loop over slices of i'th column
  88. rc++ ; # rc = number of current slice.
  89. im2(t1(j):t2(j),i) = rc ;
  90. ## if rc==341, "rc==341",keyboard; end
  91. # Slices from previous column that touch
  92. # this slice.
  93. rr = create_set(lrow(t1(j):t2(j))) ;
  94. if !isempty(rr) && !rr(1), rr = rr(2:length(rr)) ; end
  95. if rc>size(rnum,2), # Get more space (uncertain effect on
  96. # speed; avoids resizing rnum and npix)
  97. tmp = 2*(ceil(C*rc/i)-rc+1+rows(t1(:))-j) ;
  98. sayif(verbose,"bwlabel : (i=%i) Foreseeing %i more regions\n",i,tmp);
  99. rnum = [ rnum, ones(1,tmp) ] ;
  100. npix = [ npix,zeros(1,tmp) ] ;
  101. bb = [ bb,zeros(4,tmp) ] ;
  102. end
  103. if isempty(rr), # New region
  104. sayif(verbose,"bwlabel : creating region %i\n",rc);
  105. r0 = rc ; # r0 = number of the region
  106. bb(1,r0) = t1(j) ;
  107. bb(2,r0) = t2(j) ;
  108. bb(3:4,r0) = i ;
  109. else # Add to already existing region #####
  110. ## rr
  111. r0 = rnum(rr(1)) ;
  112. bb(1,r0) = min(bb(1,r0),t1(j)) ;
  113. bb(2,r0) = max(bb(2,r0),t2(j)) ;
  114. bb(4,r0) = i ;
  115. # Touches region r0
  116. sayif(verbose,"bwlabel : adding to region %i\n",r0);
  117. # Touches other regions too
  118. for k = rr(find(rr!=r0)), # Loop over other touching regions, that
  119. # should be merged to the first.
  120. sayif(verbose,"bwlabel : merging regions %i and %i\n",k,r0);
  121. rnum(find(rnum==k)) = r0 ;
  122. npix(r0) = npix(r0) + npix(k) ;
  123. bb([1,3],r0) = min(bb([1,3],r0)',bb([1,3],k)')' ;
  124. bb([2,4],r0) = max(bb([2,4],r0)',bb([2,4],k)')' ;
  125. end
  126. end # End of add to already existing region
  127. ## if r0==259 && i==39,"r0==259",keyboard;end
  128. rnum(rc) = r0 ;
  129. npix(r0) = npix(r0) + 1+t2(j)-t1(j) ;
  130. nrow(t1(j):t2(j)) = r0 ;
  131. end # End of looping over slices
  132. lrow = nrow ;
  133. if report && !verbose,
  134. printf(".") ;
  135. if !rem(i,70) && i<C, printf("\n%5i ",i); end
  136. end
  137. end # End of looping over columns
  138. ## length(regs)
  139. if report && !verbose,
  140. printf("\n") ;
  141. end
  142. ## im2
  143. ## [ 1:rc ; rnum(1:rc) ]
  144. keep = ones(1,rc) ;
  145. if mins, keep = keep & (npix(rnum(1:rc))>=mins) ; end
  146. if maxs, keep = keep & (npix(rnum(1:rc))<=maxs) ; end
  147. keep(1) = 1 ;
  148. keep = find(keep) ; # Indices of slices to be kept
  149. foo = create_set(rnum(keep)) ; # Indices of regions to be kept
  150. nr = prod(size(foo)) ; # Number of regions (including bg)
  151. ## lrow = zeros(1,nr) ;
  152. tmp = zeros(1,rc) ;
  153. tmp(foo) = 0:nr-1 ;
  154. bar = zeros(1,rc) ;
  155. bar(keep) = tmp(rnum(keep)) ;
  156. ## keyboard
  157. im2 = reshape(bar(im2),R,C) ;
  158. npix = npix(foo(2:nr));
  159. bb = bb(:,foo(2:nr));
  160. if 0, # Draw bb on the image (will ruin
  161. # coherence)
  162. for i=1:nr-1,
  163. im2([bb(1,i),bb(2,i)] ,bb(3,i):bb(4,i) ) = i ;
  164. im2( bb(1,i):bb(2,i) ,[bb(3,i),bb(4,i)]) = i ;
  165. end
  166. end
  167. ## keyboard
  168. if prudent,
  169. sayif(verbose,"bwlabel : Checking coherence\n");
  170. hcontact = im2 & im2!=[im2(:,2:C),zeros(R,1)] & [im2(:,2:C),zeros(R,1)] ;
  171. vcontact = im2 & im2!=[im2(2:R,:);zeros(1,C)] & [im2(2:R,:);zeros(1,C)] ;
  172. ok = 1 ;
  173. if any(hcontact(:)),
  174. ok = 0 ;
  175. printf("bwlabel: Whoa! Found horizontally connected separated regions\n");
  176. end
  177. if any(vcontact(:)),
  178. ok = 0 ;
  179. printf("bwlabel: Whoa! Found vertically connected separated regions\n");
  180. end
  181. if !ok, keyboard ; end
  182. end
  183. ## Eventually transpose result
  184. if tr,
  185. im2 = im2' ;
  186. bb = bb([3,4,1,2],:);
  187. end