pgmWrite.m 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. % RANGE = pgmWrite(MTX, FILENAME, RANGE, TYPE, COMMENT)
  2. %
  3. % Write a MatLab matrix to a pgm (graylevel image) file.
  4. % This format is accessible from the XV image browsing utility.
  5. %
  6. % RANGE (optional) is a 2-vector specifying the values that map to
  7. % black and white, respectively. Passing a value of 'auto' (default)
  8. % sets RANGE=[min,max] (as in MatLab's imagesc). 'auto2' sets
  9. % RANGE=[mean-2*stdev, mean+2*stdev]. 'auto3' sets
  10. % RANGE=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th percentile
  11. % value of the sorted MATRIX samples, and p2 is the 90th percentile
  12. % value.
  13. %
  14. % TYPE (optional) should be 'raw' or 'ascii'. Defaults to 'raw'.
  15. % Hany Farid, Spring '96. Modified by Eero Simoncelli, 6/96.
  16. function range = pgmWrite(mtx, fname, range, type, comment );
  17. [fid,msg] = fopen( fname, 'w' );
  18. if (fid == -1)
  19. error(msg);
  20. end
  21. %------------------------------------------------------------
  22. %% optional ARGS:
  23. if (exist('range') ~= 1)
  24. range = 'auto';
  25. end
  26. if (exist('type') ~= 1)
  27. type = 'raw';
  28. end
  29. %------------------------------------------------------------
  30. %% Automatic range calculation:
  31. if (strcmp(range,'auto1') | strcmp(range,'auto'))
  32. [mn,mx] = range2(mtx);
  33. range = [mn,mx];
  34. elseif strcmp(range,'auto2')
  35. stdev = sqrt(var2(mtx));
  36. av = mean2(mtx);
  37. range = [av-2*stdev,av+2*stdev]; % MAGIC NUMBER: 2 stdevs
  38. elseif strcmp(range, 'auto3')
  39. percentile = 0.1; % MAGIC NUMBER: 0<p<0.5
  40. [N,X] = histo(mtx);
  41. binsz = X(2)-X(1);
  42. N = N+1e-10; % Ensure cumsum will be monotonic for call to interp1
  43. cumN = [0, cumsum(N)]/sum(N);
  44. cumX = [X(1)-binsz, X] + (binsz/2);
  45. ctrRange = interp1(cumN,cumX, [percentile, 1-percentile]);
  46. range = mean(ctrRange) + (ctrRange-mean(ctrRange))/(1-2*percentile);
  47. elseif isstr(range)
  48. error(sprintf('Bad RANGE argument: %s',range))
  49. end
  50. if ((range(2) - range(1)) <= eps)
  51. range(1) = range(1) - 0.5;
  52. range(2) = range(2) + 0.5;
  53. end
  54. %%% First line contains ID string:
  55. %%% "P1" = ascii bitmap, "P2" = ascii greymap,
  56. %%% "P3" = ascii pixmap, "P4" = raw bitmap,
  57. %%% "P5" = raw greymap, "P6" = raw pixmap
  58. if strcmp(type,'raw')
  59. fprintf(fid,'P5\n');
  60. format = 5;
  61. elseif strcmp(type,'ascii')
  62. fprintf(fid,'P2\n');
  63. format = 2;
  64. else
  65. error(sprintf('PGMWRITE: Bad type argument: %s',type));
  66. end
  67. fprintf(fid,'# MatLab PGMWRITE file, saved %s\n',date);
  68. if (exist('comment') == 1)
  69. fprintf(fid,'# %s\n', comment);
  70. end
  71. %%% dimensions
  72. fprintf(fid,'%d %d\n',size(mtx,2),size(mtx,1));
  73. %%% Maximum pixel value
  74. fprintf(fid,'255\n');
  75. %% MatLab's "fprintf" floors when writing floats, so we compute
  76. %% (mtx-r1)*255/(r2-r1)+0.5
  77. mult = (255 / (range(2)-range(1)));
  78. mtx = (mult * mtx) + (0.5 - mult * range(1));
  79. mtx = max(-0.5+eps,min(255.5-eps,mtx));
  80. if (format == 2)
  81. count = fprintf(fid,'%d ',mtx');
  82. elseif (format == 5)
  83. count = fwrite(fid,mtx','uchar');
  84. end
  85. fclose(fid);
  86. if (count ~= size(mtx,1)*size(mtx,2))
  87. fprintf(1,'Warning: File output terminated early!');
  88. end
  89. %%% TEST:
  90. % foo = 257*rand(100)-1;
  91. % pgmWrite(foo,'foo.pgm',[0 255]);
  92. % foo2=pgmRead('foo.pgm');
  93. % size(find((foo2-round(foo))~=0))
  94. % foo(find((foo2-round(foo))~=0))