PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/R2-1-x/octave-forge/main/image/edge.m

#
MATLAB | 240 lines | 220 code | 19 blank | 1 comment | 16 complexity | b9e8853110860bf790bb81d29fd04f23 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. function [imout, thresh] = edge( im, method, thresh, param2 )
  2. # EDGE: find image edges
  3. # [imout, thresh] = edge( im, method, thresh, param2 )
  4. #
  5. # OUTPUT
  6. # imout -> output image
  7. # thresh -> output thresholds
  8. #
  9. # INPUT
  10. # im -> input image (greyscale)
  11. # thresh -> threshold value (value is estimated if not given)
  12. #
  13. # The following methods are based on high pass filtering the image in
  14. # two directions, calculating a combined edge weight from and then thresholding
  15. #
  16. # method = 'roberts'
  17. # filt1= [1 0 ; 0 -1]; filt2= rot90( filt1 )
  18. # combine= sqrt( filt1^2 + filt2^2 )
  19. # method = 'sobel'
  20. # filt1= [1 2 1;0 0 0;-1 -2 -1]; filt2= rot90( filt1 )
  21. # combine= sqrt( filt1^2 + filt2^2 )
  22. # method = 'prewitt'
  23. # filt1= [1 1 1;0 0 0;-1 -1 -1]; filt2= rot90( filt1 )
  24. # combine= sqrt( filt1^2 + filt2^2 )
  25. # method = 'kirsh'
  26. # filt1= [1 2 1;0 0 0;-1 -2 -1]; filt2 .. filt8 are 45 degree rotations of filt1
  27. # combine= max( filt1 ... filt8 )
  28. #
  29. # methods based on filtering the image and finding zero crossings
  30. #
  31. # method = 'log' -> Laplacian of Gaussians
  32. # param2 is the standard deviation of the filter, default is 2
  33. # method = 'zerocross' -> generic zero-crossing filter
  34. # param2 is the user supplied filter
  35. #
  36. # method = 'andy' -> my idea
  37. # A.Adler's idea (c) 1999. somewhat based on the canny method
  38. # Step 1: Do a sobel edge detection and to generate an image at
  39. # a high and low threshold
  40. # Step 2: Edge extend all edges in the LT image by several pixels,
  41. # in the vertical, horizontal, and 45degree directions.
  42. # Combine these into edge extended (EE) image
  43. # Step 3: Dilate the EE image by 1 step
  44. # Step 4: Select all EE features that are connected to features in
  45. # the HT image
  46. #
  47. # Parameters:
  48. # param2(1)==0 or 4 or 8 -> perform x connected dilatation (step 3)
  49. # param2(2) dilatation coeficient (threshold) in step 3
  50. # param2(3) length of edge extention convolution (step 2)
  51. # param2(4) coeficient of extention convolution in step 2
  52. # defaults = [8 1 3 3]
  53. # Copyright (C) 1999 Andy Adler
  54. # This code has no warrany whatsoever.
  55. # Do what you like with this code as long as you
  56. # leave this copyright in place.
  57. #
  58. # $Id: edge.m 187 2002-03-17 02:38:52Z aadler $
  59. [n,m]= size(im);
  60. xx= 2:m-1;
  61. yy= 2:n-1;
  62. if strcmp(method,'roberts') || strcmp(method,'sobel') || ...
  63. strcmp(method,'prewitt')
  64. if strcmp(method,'roberts')
  65. filt= [1 0;0 -1]/4; tv= 6;
  66. elseif strcmp(method,'sobel')
  67. filt= [1 2 1;0 0 0; -1 -2 -1]/8; tv= 2;
  68. elseif strcmp(method,'prewitt')
  69. filt= [1 1 1;0 0 0; -1 -1 -1]/6; tv= 4;
  70. end
  71. imo= conv2(im, rot90(filt), 'same').^2 + conv2(im, filt, 'same').^2;
  72. # check to see if the user supplied a threshold
  73. # if not, calculate one in the same way as Matlab
  74. if nargin<3
  75. thresh= sqrt( tv* mean(mean( imo(yy,xx) )) );
  76. end
  77. # The filters are defined for sqrt(imo), but since we calculated imo, compare
  78. # to thresh ^2
  79. imout= ( imo >= thresh^2 );
  80. # Thin the wide edges
  81. xpeak= imo(yy,xx-1) <= imo(yy,xx) & imo(yy,xx) > imo(yy,xx+1) ;
  82. ypeak= imo(yy-1,xx) <= imo(yy,xx) & imo(yy,xx) > imo(yy+1,xx) ;
  83. imout(yy,xx)= imout(yy,xx) & ( xpeak | ypeak );
  84. elseif strcmp(method,'kirsch')
  85. filt1= [1 2 1;0 0 0;-1 -2 -1]; fim1= conv2(im,filt1,'same');
  86. filt2= [2 1 0;1 0 -1;0 -1 -2]; fim2= conv2(im,filt2,'same');
  87. filt3= [1 0 -1;2 0 -2;1 0 -1]; fim3= conv2(im,filt3,'same');
  88. filt4= [0 1 2;-1 0 1;-2 -1 0]; fim4= conv2(im,filt4,'same');
  89. imo= reshape(max([abs(fim1(:)) abs(fim2(:)) abs(fim3(:)) abs(fim4(:))]'),n,m);
  90. if nargin<3
  91. thresh= 2* mean(mean( imo(yy,xx) )) ;
  92. end
  93. imout= imo >= thresh ;
  94. # Thin the wide edges
  95. xpeak= imo(yy,xx-1) <= imo(yy,xx) & imo(yy,xx) > imo(yy,xx+1) ;
  96. ypeak= imo(yy-1,xx) <= imo(yy,xx) & imo(yy,xx) > imo(yy+1,xx) ;
  97. imout(yy,xx)= imout(yy,xx) & ( xpeak | ypeak );
  98. elseif strcmp(method,'log') || strcmp(method,'zerocross')
  99. if strcmp(method,'log')
  100. if nargin >= 4; sd= param2;
  101. else sd= 2;
  102. end
  103. sz= ceil(sd*3);
  104. [x,y]= meshgrid( -sz:sz, -sz:sz );
  105. filt = exp( -( x.^2 + y.^2 )/2/sd^2 ) .* ...
  106. ( x.^2 + y.^2 - 2*sd^2 ) / 2 / pi / sd^6 ;
  107. else
  108. filt = param2;
  109. end
  110. filt = filt - mean(filt(:));
  111. imo= conv2(im, filt, 'same');
  112. if nargin<3 || isempty( thresh )
  113. thresh= 0.75* mean(mean( abs(imo(yy,xx)) )) ;
  114. end
  115. zcross= imo > 0;
  116. yd_zc= diff( zcross );
  117. xd_zc= diff( zcross' )';
  118. yd_io= abs(diff( imo ) ) > thresh;
  119. xd_io= abs(diff( imo')') > thresh;
  120. # doing it this way puts the transition at the <=0 point
  121. xl= zeros(1,m); yl= zeros(n,1);
  122. imout= [ ( yd_zc == 1 ) & yd_io ; xl] | ...
  123. [xl; ( yd_zc == -1 ) & yd_io ] | ...
  124. [ ( xd_zc == 1 ) & xd_io , yl] | ...
  125. [yl, ( xd_zc == -1 ) & xd_io ];
  126. elseif strcmp(method,'canny')
  127. error("method canny not implemented");
  128. elseif strcmp(method,'andy')
  129. filt= [1 2 1;0 0 0; -1 -2 -1]/8; tv= 2;
  130. imo= conv2(im, rot90(filt), 'same').^2 + conv2(im, filt, 'same').^2;
  131. if nargin<3 || thresh==[];
  132. thresh= sqrt( tv* mean(mean( imo(yy,xx) )) );
  133. end
  134. # sum( imo(:)>thresh ) / prod(size(imo))
  135. dilate= [1 1 1;1 1 1;1 1 1]; tt= 1; sz=3; dt=3;
  136. if nargin>=4
  137. # 0 or 4 or 8 connected dilation
  138. if length(param2) > 0
  139. if param2(1)==4 ; dilate= [0 1 0;1 1 1;0 1 0];
  140. elseif param2(1)==0 ; dilate= 1;
  141. end
  142. end
  143. # dilation threshold
  144. if length(param2) > 2; tt= param2(2); end
  145. # edge extention length
  146. if length(param2) > 2; sz= param2(3); end
  147. # edge extention threshold
  148. if length(param2) > 3; dt= param2(4); end
  149. end
  150. fobliq= [0 0 0 0 1;0 0 0 .5 .5;0 0 0 1 0;0 0 .5 .5 0;0 0 1 0 0;
  151. 0 .5 .5 0 0;0 1 0 0 0;.5 .5 0 0 0;1 0 0 0 0];
  152. fobliq= fobliq( 5-sz:5+sz, 3-ceil(sz/2):3+ceil(sz/2) );
  153. xpeak= imo(yy,xx-1) <= imo(yy,xx) & imo(yy,xx) > imo(yy,xx+1) ;
  154. ypeak= imo(yy-1,xx) <= imo(yy,xx) & imo(yy,xx) > imo(yy+1,xx) ;
  155. imht= ( imo >= thresh^2 * 2); # high threshold image
  156. imht(yy,xx)= imht(yy,xx) & ( xpeak | ypeak );
  157. imht([1,n],:)=0; imht(:,[1,m])=0;
  158. % imlt= ( imo >= thresh^2 / 2); # low threshold image
  159. imlt= ( imo >= thresh^2 / 1); # low threshold image
  160. imlt(yy,xx)= imlt(yy,xx) & ( xpeak | ypeak );
  161. imlt([1,n],:)=0; imlt(:,[1,m])=0;
  162. # now we edge extend the low thresh image in 4 directions
  163. imee= ( conv2( imlt, ones(2*sz+1,1) , 'same') > tt ) | ...
  164. ( conv2( imlt, ones(1,2*sz+1) , 'same') > tt ) | ...
  165. ( conv2( imlt, eye(2*sz+1) , 'same') > tt ) | ...
  166. ( conv2( imlt, rot90(eye(2*sz+1)), 'same') > tt ) | ...
  167. ( conv2( imlt, fobliq , 'same') > tt ) | ...
  168. ( conv2( imlt, fobliq' , 'same') > tt ) | ...
  169. ( conv2( imlt, rot90(fobliq) , 'same') > tt ) | ...
  170. ( conv2( imlt, flipud(fobliq) , 'same') > tt );
  171. # imee(yy,xx)= conv2(imee(yy,xx),ones(3),'same') & ( xpeak | ypeak );
  172. imee= conv2(imee,dilate,'same') > dt; #
  173. % ff= find( imht==1 );
  174. % imout = bwselect( imee, rem(ff-1, n)+1, ceil(ff/n), 8);
  175. imout = imee;
  176. else
  177. error (['Method ' method ' is not recognized']);
  178. end
  179. #
  180. # $Log$
  181. # Revision 1.1 2002/03/17 02:38:52 aadler
  182. # fill and edge detection operators
  183. #
  184. # Revision 1.4 2000/11/20 17:13:07 aadler
  185. # works?
  186. #
  187. # Revision 1.3 1999/06/09 17:29:36 aadler
  188. # implemented 'andy' mode edge detection
  189. #
  190. # Revision 1.2 1999/06/08 14:26:50 aadler
  191. # zero-cross and LoG filters work
  192. #
  193. # Revision 1.1 1999/06/07 21:01:38 aadler
  194. # Initial revision
  195. #
  196. #
  197. #