boxcount.m
上传用户:cz_hongli
上传日期:2015-05-14
资源大小:1613k
文件大小:5k
源码类别:

分形几何

开发平台:

Matlab

  1. function [n,r] = boxcount(c,varargin)
  2. %BOXCOUNT  Box-Counting of a D-dimensional array (with D=1,2,3).
  3. %   [N, R] = BOXCOUNT(C), where C is a D-dimensional array (with D=1,2,3),
  4. %   counts the number N of D-dimensional boxes of size R needed to cover
  5. %   the nonzero elements of C. The box sizes are powers of two, i.e., 
  6. %   R = 1, 2, 4 ... 2^P, where P is the smallest integer such that
  7. %   MAX(SIZE(C)) <= 2^P. If the sizes of C over each dimension are smaller
  8. %   than 2^P, C is padded with zeros to size 2^P over each dimension (e.g.,
  9. %   a 320-by-200 image is padded to 512-by-512). The output vectors N and R
  10. %   are of size P+1. For a RGB color image (m-by-n-by-3 array), a summation
  11. %   over the 3 RGB planes is done first.
  12. %
  13. %   The Box-counting method is useful to determine fractal properties of a
  14. %   1D segment, a 2D image or a 3D array. If C is a fractal set, with
  15. %   fractal dimension DF < D, then N scales as R^(-DF). DF is known as the
  16. %   Minkowski-Bouligand dimension, or Kolmogorov capacity, or Kolmogorov
  17. %   dimension, or simply box-counting dimension.
  18. %
  19. %   BOXCOUNT(C,'plot') also shows the log-log plot of N as a function of R
  20. %   (if no output argument, this option is selected by default).
  21. %
  22. %   BOXCOUNT(C,'slope') also shows the semi-log plot of the local slope
  23. %   DF = - dlnN/dlnR as a function of R. If DF is contant in a certain
  24. %   range of R, then DF is the fractal dimension of the set C.
  25. %
  26. %   The execution time depends on the sizes of C. It is fastest for powers
  27. %   of two over each dimension.
  28. %
  29. %   Examples:
  30. %
  31. %      % Plots the box-count of a vector containing randomly-distributed
  32. %      % 0 and 1. This set is not fractal: one has N = R^-2 at large R,
  33. %      % and N = cste at small R.
  34. %      c = (rand(1,2048)<0.2);
  35. %      boxcount(c);
  36. %
  37. %      % Plots the box-count and the fractal dimension of a 2D fractal set
  38. %      % of size 512^2 (obtained by BOXDIV), with fractal dimension
  39. %      % DF = 2 + log(P) / log(2) = 1.68 (with P=0.8).
  40. %      c = randcantor(0.8, 512, 2);
  41. %      boxcount(c);
  42. %      figure, boxcount(c, 'slope');
  43. %
  44. %   F. Moisy
  45. %   Revision: 2.00,  Date: 2006/11/22
  46. % History:
  47. % 2006/11/22: joins into a single file boxcountn (n=1,2,3).
  48. % control input argument
  49. error(nargchk(1,2,nargin));
  50. % check for true color image (m-by-n-by-3 array)
  51. if ndims(c)==3
  52.     if size(c,3)==3 && size(c,1)>=8 && size(c,1)>=8
  53.         c = sum(c,3);
  54.     end;
  55. end;
  56. warning off
  57. c = logical(squeeze(c));
  58. warning on
  59. dim = ndims(c); % dim is 2 for a vector or a matrix, 3 for a cube
  60. if dim>3
  61.     error('Maximum dimension is 3.');
  62. end
  63. % transpose the vector to a 1-by-n vector
  64. if length(c)==numel(c)
  65.     dim=1;
  66.     if size(c,1)~=1   
  67.         c = c';
  68.     end   
  69. end
  70. width = max(size(c));    % largest size of the box
  71. p = log(width)/log(2);   % nbre of generations
  72. % remap the array if the sizes are not all equal,
  73. % or if they are not power of two
  74. % (this slows down the computation!)
  75. if p~=round(p) || any(size(c)~=width)
  76.     p = ceil(p);
  77.     width = 2^p;
  78.     switch dim
  79.         case 1
  80.             mz = zeros(1,width);
  81.             mz(1:length(c)) = c;
  82.             c = mz;
  83.         case 2
  84.             mz = zeros(width, width);
  85.             mz(1:size(c,1), 1:size(c,2)) = c;
  86.             c = mz;
  87.         case 3
  88.             mz = zeros(width, width, width);
  89.             mz(1:size(c,1), 1:size(c,2), 1:size(c,3)) = c;
  90.             c = mz;            
  91.     end
  92. end
  93. n=zeros(1,p+1); % pre-allocate the number of box of size r
  94. switch dim
  95.     case 1        %------------------- 1D boxcount ---------------------%
  96.         n(p+1) = sum(c);
  97.         for g=(p-1):-1:0
  98.             siz = 2^(p-g);
  99.             siz2 = round(siz/2);
  100.             for i=1:siz:(width-siz+1)
  101.                 c(i) = ( c(i) || c(i+siz2));
  102.             end
  103.             n(g+1) = sum(c(1:siz:(width-siz+1)));
  104.         end
  105.     case 2         %------------------- 2D boxcount ---------------------%
  106.         n(p+1) = sum(c(:));
  107.         for g=(p-1):-1:0
  108.             siz = 2^(p-g);
  109.             siz2 = round(siz/2);
  110.             for i=1:siz:(width-siz+1)
  111.                 for j=1:siz:(width-siz+1)
  112.                     c(i,j) = ( c(i,j) || c(i+siz2,j) || c(i,j+siz2) || c(i+siz2,j+siz2) );
  113.                 end
  114.             end
  115.             n(g+1) = sum(sum(c(1:siz:(width-siz+1),1:siz:(width-siz+1))));
  116.         end
  117.     case 3         %------------------- 3D boxcount ---------------------%
  118.         n(p+1) = sum(c(:));
  119.         for g=(p-1):-1:0
  120.             siz = 2^(p-g);
  121.             siz2 = round(siz/2);
  122.             for i=1:siz:(width-siz+1),
  123.                 for j=1:siz:(width-siz+1),
  124.                     for k=1:siz:(width-siz+1),
  125.                         c(i,j,k)=( c(i,j,k) || c(i+siz2,j,k) || c(i,j+siz2,k) ...
  126.                             || c(i+siz2,j+siz2,k) || c(i,j,k+siz2) || c(i+siz2,j,k+siz2) ...
  127.                             || c(i,j+siz2,k+siz2) || c(i+siz2,j+siz2,k+siz2));
  128.                     end
  129.                 end
  130.             end
  131.             n(g+1) = sum(sum(sum(c(1:siz:(width-siz+1),1:siz:(width-siz+1),1:siz:(width-siz+1)))));
  132.         end
  133. end
  134. n = n(end:-1:1);
  135. r = 2.^(0:p); % box size (1, 2, 4, 8...)
  136. if any(strncmpi(varargin,'slope',1))
  137.     s=-diff(log(n))./diff(log(r));
  138.     semilogx(r(1:end-1), s, 's-');
  139.     a=axis;
  140.     axis([a(1) a(2) 0 dim]);
  141.     xlabel('r, box size'); ylabel('- d ln n / d ln r, local dimension');
  142.     title([num2str(dim) 'D box-count']);
  143. elseif nargout==0 || any(strncmpi(varargin,'plot',1))
  144.     loglog(r,n,'s-');
  145.     xlabel('r, box size'); ylabel('n(r), number of boxes');
  146.     title([num2str(dim) 'D box-count']);
  147. end
  148. if nargout==0
  149.     clear r n
  150. end