function mtfcurveA(varargin) % version 04/30/2002 % Visualize the effects of MTF (modulation transfer function) % in film, lenses, scanners, and sharpening using simulation. Format: % mtfcurveA f50 % f50 is the 50% MTF density of film in line pairs/mm, typically 20 - 60. % mtfcurveA f50 fboost % fboost is the frequency shift of the 2nd order equalizer. % mtfcurveA f50 fboost flens % flens is the 50% MTF density of the lens. % mtfcurveA f50 fboost flens lord % lord is lens rolloff order (default = 2). % mtfcurveA f50 fboost flens lord dscan sincpwr % dscan is scanner pixels per mm (dpmm). % sincpwr is the power of the sinc function describing the scanner or digital sensor roloff. % mtfcurveA f50 fboost flens lord dscan sincpwr ksharp % ksharp is sharpening boost. % % mtfcurveA 45 13 61 2 4000/25.4 3 % test example % % Parameters default to 0 if not entered, except lord=2. % If f50<0, Create printer test targets. |f50| is the 50% film density. % If fboost>0, a boost is applied by shifting the peak frequency of the rolloff. % normal: 1/(1+(f/f50)^2) % with fboost: k1/(1+((f-fboost)/f50a)^2) , where k1 normalizes response to 1 % at f=0 and f50a is set so f50 remains the 50% MTF density. fboost < f50/2. % If flens>0, a simplified lens MTF is added to the transfer, using 1/(1+(f/flens)^2) % If abs(dscan)>0, a scanner with dscan dpmm (pixels/mm) is added. % sincpwr is the exponent of the sinc functhin describing scanner MTF: |sinc|^sincpwr % 3 is appropriate for a film scanner; 2 for a Bayer sensor digital camera; % 1 for a Foveon X3 digital camera; 4 or 5 for an inexpensive flatbed scanner. % If abs(ksharp)>0, sharpening equivalent to a cosine boost is applied, where ksharp is % the amount of boost. Sharpening radius rsharp = 1 if ksharp>0; 2 if ksharp<0. % Equation: (1+|ksharp|*cos(2*pi*f*rsharp/dscan))/(1+|ksharp|) %%%%%%%%%%%%%% % % Copyright (C) 2001-2004 by Norman Koren, http://www.normankoren.com normkoren@earthlink.net % Every conceivable disclaimer applies; the author assumes no legal liability whatsoever. % You may distribute this program freely, but please maintain the original copyright. fboost = 0; flens = 0; lord = 2; dscan=0; ksharp=0; % Defaults. if (nargin==0 | nargin>7) error(['Entered ' num2str(nargin) ' arguments. Must enter 1 - 6.']); end if (nargin>=1) f50 = abs(str2num(varargin{1})); % Density (line pairs per mm) of 50% MTF. descript = ['f50 = ' num2str(f50,4) ' lp/mm']; end prtarg = ((str2num(varargin{1}))<0); % Create printer target if first argument <0. if (nargin>=2) % Boost frequency from cosine eql or peak center shift. fboost = str2num(varargin{2}); % Boost by shifting peak if (fboost>eps) descript = [descript '; fboost = ' num2str(fboost,4) ' lp/mm']; end, end if (nargin>=3) % Lens f50. flens = str2num(varargin{3}); % Lens 50% density. descript = [descript '; flens = ' num2str(flens,4) ' lp/mm']; end if (nargin>=4) % Lens rolloff order (default 2). lord = str2num(varargin{4}); % Lens 50% density. if (lord.45*f50) % Boost by shifting peak. error(['fboost must be < .45*f50 = ' num2str(.45*f50,4)]); end close all xmax = 0.5; % Maximum of x1 in mm. The physical length of the image. ymax = 200; % Maximum line pairs per mm (spatial frequency) the plots. ncyc = log10(100); % Cycles of frequency to display. Argument is frequency ratio. ymin = ymax/10^ncyc; ymid = ymax/10^(ncyc/2); % Minimum, middle spatial frequencies. lfft = 2048; % Total array length; ldisp = 1920; % Length to display; lgr = lfft-ldisp; % Length of gray needed to avoid cyclic problems. ld1 = ldisp-1; lf2 = lfft/2; x1 = ([0:ld1]/ld1)*xmax; % Distance in mm along axis to display. xinc = x1(2)-x1(1); % x1 (spatial) increment in mm. fdel = 1/(lfft*xinc); % Spatial frequency increment in 1/mm. fq1 = 10.^(ncyc*[0:ld1]/ld1); fq1 = ymax*fq1/max(fq1); % Spatial frequency 1/mm. xint = 1/ld1; % Substitute for xinc % figure; semilogy([0:ld1]*xint,fq1); grid on; zoom on; % ax = axis; ax(2) = ld1*xint; ax(4) = ymax; axis(ax); % title('Spatial frequency as a function of distance'); % xlabel('Normalized distance'); ylabel('Spatial frequency in line pairs per mm (1/mm)'); % p1 = get(gcf,'Position'); p1(4) = .8*p1(4); p1(3) = .8*p1(3); set(gcf,'Position',p1); u1 = 2.*pi*cumsum(fq1)*xinc; % Equation for varying frequency is tricky! ycos = .5*(1+cos(u1)); % Original cosine pattern before rounding. temp = find(round(ycos(1:ldisp-1))~=round(ycos(2:ldisp))); % Anti-aliasing calculation. temp1 = (.5-ycos(temp))./(ycos(temp+1)-ycos(temp)); % Fraction for crossing. ybw = round(ycos); % {0,1} Basic black/white pattern to analyze. ybw(temp+round(temp1)) = (1-abs(temp1-.5)).*ybw(temp+ round(temp1)) + ... (abs(temp1-.5)) .*ybw(temp+1-round(temp1)); clear temp,temp1; % figure; plot(x1,ycos,x1,ybw); zoom on; % For test. %%%%%%%%%%%%%%%%%%% half = .5*ones(1,lgr); ybw = [ybw half]; ycos = [ycos half]; % Last lgr points have a value of 1/2. if (prtarg) % COUNTERPARTS FOR PRINTER xpmax = 10; % Max x1 mm for printer test image. lpfft = 16384; lpdsp = 15360; lpgr = lpfft-lpdsp; % Counterparts of lfft... for printer. lpd1 = lpdsp-1; lpf2 = lpfft/2; xp1 = ([0:lpd1]/lpd1)*xpmax; % Distance in mm along axis to display. xpinc = xpmax/lpd1; % Spatial increment in mm. fpel = 1/(lpfft*xpinc); fpq1 = 10.^(ncyc*[0:lpd1]/lpd1); fpq1 = ymax*fpq1/max(fpq1); % Spatial frequency 1/mm. u1 = 2.*pi*cumsum(fpq1)*xpinc; % Equation for varying frequency is tricky! ypw = .5*(1+cos(u1)); % Original cosine pattern before rounding. temp = find(round(ypw(1:lpdsp-1))~=round(ypw(2:lpdsp))); % Anti-aliasing calculation. temp1 = (.5-ypw(temp))./(ypw(temp+1)-ypw(temp)); % Fraction for crossing. ypw = round(ypw); % {0,1} basic black/white pattern to analyze. Comment out for testing. ypw(temp+round(temp1)) = (1-abs(temp1-.5)).*ypw(temp+ round(temp1)) + ... (abs(temp1-.5)) .*ypw(temp+1-round(temp1)); clear temp, temp1; % figure; plot(1:lpdsp,ypw,'bx-'); zoom on; %%%%%%% % ax = axis; ax(3) = -1; ax(4) = 2; axis(ax); %%%%%%% phalf = .5*ones(1,lpgr); ypw = [ypw phalf]; % Last lgr points have a value of 1/2. end % END PRINTER FOR NOW. cmap = zeros(256,3); % Color map: gray scale. Apparently gamma corrected. gamma = 1; cmap(1:256,1) = ([0:255]'/255).^(1/gamma); cmap(1:256,2) = cmap(1:256,1); cmap(1:256,3) = cmap(1:256,1); lvon = 40; lv2 = ceil(.4*lvon); % Lvon is pattern height. lv2 is text position. vones = ones([lvon 1]); % Start sequence display. yp2 = real(ybw(1:ldisp)); yp3 = vones*yp2; % Original bands. yp3 is a 2D matrix. yp3 = yp3-min(min(yp3)); yp3 = yp3/max(max(yp3)); % Normalize plot. ypp = yp3; % Original bands f1 = fft(ybw); f1cos = fft(ycos); fq2 = [0:lf2, -lf2+1:-1]; % figure; plot(fq2,real(f1),fq2,imag(f1)); grid on; zoom on; tfrfn = 1./(1+(fq2*fdel/f50).^2); % MTF (without cos boost). if (prtarg) fp1 = fft(ypw); fp2 = [0:lpf2,-lpf2+1:-1]; % For printer. pfrfn = 1./(1+(fp2*fpel/f50).^2); end % MTF (without cos boost). % Add cosine boost, but not at high frequencies. Use tricks. if (fboost>eps) % MTF with shifted zero point. tfrfn = 1./(1+((abs(fq2*fdel)-fboost)/sqrt(f50^2-2*f50*fboost-fboost^2)).^2); tfrfn = tfrfn/tfrfn(1); % normalize tfrfn to lowest frequency. if (prtarg) pfrfn = 1./(1+((abs(fp2*fpel)-fboost)/sqrt(f50^2-2*f50*fboost-fboost^2)).^2); % Printer pfrfn = pfrfn/pfrfn(1); end % normalize tfrfn to lowest frequency. end if (flens>eps) % LENS tlens = 1./(1+abs(fq2*fdel/flens).^lord); % Lens MTF. Order (lord) defaults to 2. if (prtarg) plens = 1./(1+abs(fp2*fpel/flens).^lord); end % Lens MTF for printer. f2 = ifft(tlens.*f1); % Lens only. yp2 = real(f2(1:ldisp)); yp3 = vones*yp2; % Lens only. yp3 is a 2D matrix. yp3 = yp3-min(min(yp3)); yp3 = yp3/max(max(yp3)); % Normalize plot. ypp = [ypp ; yp3]; % LENS f2 = ifft(tfrfn.*f1); if (f50>eps & f50<999) % Omit film. yp2 = real(f2(1:ldisp)); yp3 = vones*yp2; % Lens only. yp3 is a 2D matrix. yp3 = yp3-min(min(yp3)); yp3 = yp3/max(max(yp3)); % Normalize plot. ypp = [ypp ; yp3]; % FILM end tfrfn = tfrfn.*tlens; % Make tfrfn lens + film. if (prtarg) pfrfn = pfrfn.*plens; end end % Multiply tfrfn by lens MTF. [t50,i50] = min((tfrfn(1:lf2)-.5).^2); fq50 = fq2(i50)*fdel; % Find 50% point. if (tfrfn(i50)>.5) i51 = i50+1; else i51 = i50-1; end f51 = abs((tfrfn(i50)-.5)/(tfrfn(i50)-tfrfn(i51))); % Fraction i51 for interpolation. fq50 = fdel*((1-f51)*fq2(i50)+f51*fq2(i51)); % 50% point by interpolation. [t10,i10] = min((tfrfn(1:lf2)-.1).^2); fq10 = fq2(i10)*fdel; % Find 10% point. if (tfrfn(i10)>.1) i11 = i10+1; else i11 = i10-1; end f11 = abs((tfrfn(i10)-.1)/(tfrfn(i10)-tfrfn(i11))); % Fraction i11 for interpolation. fq10 = fdel*((1-f11)*fq2(i10)+f11*fq2(i11)); % 10% point by interpolation. % figure; loglog(fq2(2:lf2)*fdel,100*tfrfn(2:lf2)); grid on; zoom on; % ax = axis; ax(1) = ymin; ax(2) = ymax; ax(3) = 1; % if (max(tfrfn)<2 & ax(4)>200) ax(4) = 200; end; axis(ax); xlblm = ['Line pairs per mm; MTF = 50%,10% @ ' num2str(fq50,3) ', ' num2str(fq10,3) '/mm']; if (fboost>eps) xlblm = [xlblm '; Max MTF = ',num2str(max(tfrfn),3)]; end % xlabel(xlblm); title(descript); f2 = ifft(tfrfn.*f1); f2cos = ifft(tfrfn.*f1cos); yp2 = real(f2(1:ldisp)); yp3 = vones*yp2; % yp3 is a 2D matrix. Lens+film yp3 = yp3-min([min(yp3) 0]); yp3 = yp3/max([max(yp3) 1]); % Normalize plot. if (f50>eps & f50<999) ypp = [ypp ; yp3]; end % LENS + FILM if (prtarg)fp2 = ifft(pfrfn.*fp1); %%%%%%%%%%%%%%% FOR PRINTER %%%%%%%%%%%% figure; plot([0:lpd1]*xpinc,real(fp2(1:lpdsp)),[0:lpd1]*xpinc,imag(fp2(1:lpdsp))); %%%%%% ax = axis; ax(2) = lpd1*xpinc; axis(ax); %%%%%%% title('For printer'); grid on; zoom on; %%%%%%% end y6 = real(f2); y6cos = real(f2cos(1:ldisp)); y6 = y6-min([min(y6(1:ldisp)) 0]); y6 = y6/max([max(y6(1:ldisp)) 1]); % Normalize plot. y6cos = y6cos-min([min(y6cos(1:ldisp)) 0]); y6cos = y6cos/max([max(y6cos(1:ldisp)) 1]); y7 = ones(12,1)*ycos(1:ldisp); y7 = [y7; ones(38,1)*y6cos]; % y7(13:50,:) y7 = [y7; ones(12,1)*ybw(1:ldisp)]; % y7(13:50,:) y7 = [y7; ones(38,1)*y6(1:ldisp)]; % y7(63:100,:) imwrite(y7,'MTFcurve_image_1.tif','tif'); % COMBINED PLOT figure; p1 = get(gcf,'Position'); p1(2) = p1(2)-60; p1(4) = p1(4)+60; p1(3) = p1(3)-80; set(gcf,'Position',p1); p2 = get(gcf,'PaperPosition'); p2(2) = p2(2)-1; p2(4) = p2(4)+2; set(gcf,'PaperPosition',p2); subplot('Position',[.10 .4 .88 .55]); % [l b w h] image(255*y7); colormap(cmap); % get(gcf) gets properties. h = gca; set(h,'YTickLabel',{' '}); set(h,'XTickLabel',{' '}); title(descript); ylabel('Bar pattern (bottom); Sine pattern (top)'); htxt = text(ldisp/20, 6,['Sine pattern: Original']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') htxt = text(ldisp/20,56,['Bar pattern: Original']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') if (flens5000) htxt = text(ldisp/20,69,['Bar pattern: Lens only']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') htxt = text(ldisp/20,19,['Sine pattern: Lens only']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') else htxt = text(ldisp/20,69,['Bar pattern: Film & lens']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') htxt = text(ldisp/20,19,['Sine pattern: Film & lens']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') end subplot('Position',[.10 .09 .88 .31]); % [l b w h] loglog(fq2(2:lf2)*fdel,100*tfrfn(2:lf2),'b-', 'LineWidth',1.5); grid on; zoom on; hold on; loglog(fq1,10.^(2*y6(1:ldisp)),'r-', 'LineWidth',1.5); if (flens>eps) loglog(fq2(2:lf2)*fdel,100*tlens(2:lf2),'b:'); end plot([2 200],[10 10],'r--'); plot([2 200],[50 50],'b:'); hold off; ax = axis; ax(1) = ymin; ax(2) = ymax; % ax(3) = 1; % old ax(3) = min(1, min(10.^(2*y6(1:ldisp)))); ax(4) = max([100 max(10.^(2*y6(1:ldisp))) max(100*tfrfn(2:lf2))]); axis(ax); xlabel(xlblm); ylabel('MTF %, amplitude'); if (dscan>2) % Results for a scanner with dscan pixels/mm (dscan*25.4 pixels/inch) tfrtot = tfrfn; % Total transfer function with scanner. sscan = 1/(dscan*xinc); % Scan steps in array points (non-integer). sstep = [1:sscan:lfft]; % Scan boundaries for averaging. if (sstep(length(sstep))1 & ix1>1) % fscan MUST be antialiased to avoid the jaggies! fx0 = ix1-ix0; % Weighting fraction. fscan(i2,ix1-1) = fx0*fstep(i1)+(1-fx0)*fstep(i1-1); end end if (ksharp>eps) % Sharpen the image using a cosine boost. rsharp = radius. fshp = fstep; if (rsharp==1) fshp(2:lfs-1) = (fstep(2:lfs-1)-.5*ksharp*(fstep(1:lfs-2)+fstep(3:lfs)))/(1-ksharp); else % rsharp == 2. fshp(3:lfs-2) = (fstep(3:lfs-2)-.5*ksharp*(fstep(1:lfs-4)+fstep(5:lfs)))/(1-ksharp); end for (i1=1:lfs) ix0 = max(sstep(i1)-sshft,1); % Non-integer left boundary for anti-aliasing. ix1 = ceil(ix0); ix2 = max(floor(sstep(i1+1)-sshft),1); fsharp(i2,ix1:ix2) = fshp(i1); if (i1>1 & ix1>1) % fscan MUST be antialiased to avoid the jaggies! fx0 = ix1-ix0; % Weighting fraction. fsharp(i2,ix1-1) = fx0*fshp(i1)+(1-fx0)*fshp(i1-1); end end end % End cosine boost for sharpening end if (prtarg) % PRINTER TARGET pscan =1/(dscan*xpinc); % Scan steps in points in array fp2 (non-integer). pstep = [1:pscan:lpdsp]; % Scan boundaries in array fp2 for averaging. lps = length(pstep); % Number of points (more than target length, typ. 10mm) if (pstep(length(pstep))eps) % Sharpen here using a cosine boost. if (rsharp==1) fpstep(2:lps-1) = (fpstep(2:lps-1)-.5*ksharp*(fpstep(1:lps-2)+fpstep(3:lps)))/(1-ksharp); else % rsharp == 2. fpstep(3:lps-2) = (fpstep(3:lps-2)-.5*ksharp*(fpstep(1:lps-4)+fpstep(5:lps)))/(1-ksharp); end end % End cosine boost for sharpening htarg = round(lpst/16); ht1 = round(lpst/72); ht2 = round(lpst/160); fptarg = ones(6*htarg,lpst-1); m1 = min(fpstep); m2 = max(fpstep); for (i1=1:2*htarg-1) fptarg(i1,:) = ... ((fpstep-m1)/(m2-m1)*(i1-1)+.5*(2*htarg-i1))/(2*htarg-1); end for (i1=2*htarg+7:3*htarg-1) fptarg(i1,:) = (fpstep-m1)/(m2-m1); end for (i1=3*htarg+7:4*htarg) fptarg(i1,:) = fpstep; end grayw = max(round(htarg/8),6); % Width of gray line. for (i1=2*htarg:2*htarg+grayw) fptarg(i1,:) = .5*ones(1,lpst-1); end for (i1=3*htarg:3*htarg+grayw) fptarg(i1,:) = .5*ones(1,lpst-1); end % Create tics for 2 to 200 lp/mm logarithmic scale. xt1 = log10(2); xt3 = (lpst-2)/(log10(200)-xt1); tic1 = [2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100 200]; tic2 = [2.5 3.5 15 25 35 150]; ltic1 = round(1+xt3*(log10(tic1)-xt1)); ltic2 = round(1+xt3*(log10(tic2)-xt1)); for (i1=4*htarg+1:4*htarg+1+ht1) fptarg(i1,ltic1) = 0; end for (i1=4*htarg+1:4*htarg+1+ht2) fptarg(i1,ltic2) = 0; end for (i1=5*htarg-ht1:5*htarg) fptarg(i1,ltic1) = 0; end for (i1=5*htarg-ht2:5*htarg) fptarg(i1,ltic2) = 0; end for (i1=5*htarg+1:6*htarg) fptarg(i1,:) = fporig; end imwrite(fptarg,'printarget.tif','tif'); % Write the target. fprintf(' Printer target has been written to printarget.tif.\n'); figure; subplot('Position',[.10 .44 .88 .52]); % [l b w h] image(255*fptarg); colormap(cmap); subplot('Position',[.10 .10 .88 .34]); plot(fpstep); zoom on; grid on; ax = axis; ax(2) = length(fpstep); axis(ax); % Create a super target for photographing, etc. if (0) clear fptarg % Get some memory. This target is very long. fptarg = zeros(200,lpdsp); for (i1=1:200) fptarg(i1,:) = y6(1:lpdsp); end imwrite(fptarg,'idealtgt.tif','tif'); % Write the target. end end % END PRINTER TARGET if (ksharp.5) i51 = i50+1; else i51 = i50-1; end f51 = abs((tfrtot(i50)-.5)/(tfrtot(i50)-tfrtot(i51))); % Fraction i51 for interpolation. fq50 = fdel*((1-f51)*fq2(i50)+f51*fq2(i51)); % 50% point by interpolation. [t10,i10] = min((tfrtot(1:lf2)-.1).^2); fq10 = fq2(i10)*fdel; % Find 10% point. if (tfrtot(i10)>.1) i11 = i10+1; else i11 = i10-1; end f11 = abs((tfrtot(i10)-.1)/(tfrtot(i10)-tfrtot(i11))); % Fraction i11 for interpolation. fq10 = fdel*((1-f11)*fq2(i10)+f11*fq2(i11)); % 10% point by interpolation. xlblm = ['Line pairs per mm; MTF = 50%,10% @ ' num2str(fq50,3) ', ' num2str(fq10,3) ' lp/mm']; if (fboost>eps) xlblm = [xlblm '; Max MTF = ',num2str(max(tfrfn),3)]; end % figure; loglog(fq2(2:lf2)*fdel,100*tfrscan(2:lf2)); grid on; zoom on; % hold on; loglog(fq2(2:lf2)*fdel,100*abs(tfrsc(2:lf2)),'r-'); hold off; % ax(1) = ymin; ax(2) = ymax; ax(3) = .1; ax(4) = 1000.; % if (max(tfrscan)<2 & ax(4)>200) ax(4) = 200; end; axis(ax); % xlabel(xlblm); title(descript); % COMBINED PLOT figure; p1 = get(gcf,'Position'); p1(2) = p1(2)-60; p1(4) = p1(4)+60; p1(3) = p1(3)-80; set(gcf,'Position',p1); p2 = get(gcf,'PaperPosition'); p2(2) = p2(2)-1; p2(4) = p2(4)+2; set(gcf,'PaperPosition',p2); subplot('Position',[.10 .4 .88 .55]); % [l b w h] image(255*y7); colormap(cmap); % get(gcf) gets properties. h = gca; set(h,'YTickLabel',{' '}); set(h,'XTickLabel',{' '}); htxt = text(ldisp/24, 9,['Sine pattern: Original']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') htxt = text(ldisp/24,29,['Bar pattern: Original']); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') htxt = text(ldisp/24,49,['Digitizer resolution = ' num2str(dscan,4) ' pixels/mm = ' ... num2str(dscan*25.4,4) '/in; sinc\^' num2str(sincpwr,2)]); set(htxt,'Color',[1 0 0],'Fontsize',10,'FontWeight','bold') title(descript); ylabel('Slanted, original bar pattern'); subplot('Position',[.10 .09 .88 .31]); % [l b w h] loglog(fq2(2:lf2)*fdel,100*tfrfn(2:lf2), 'b-'); hold on; loglog(fq2(2:lf2)*fdel,100*tfrtot(2:lf2),'k-','LineWidth',1.5); grid on; zoom on; % tfrscp is scanner tfr fn; tsharp is sharpening tfr fn; tfrtot is total transfer fn. if (ksharp>eps) tsn = max(tfrtot(2:lf2))/max(tfrscp(2:lf2).*tsharp(2:lf2)); % Normalize. loglog(fq2(2:lf2)*fdel,100*tfrscp(2:lf2).*tsharp(2:lf2)*tsn,'b:','LineWidth',1.5); else loglog(fq2(2:lf2)*fdel,100*tfrscp(2:lf2),'b--', 'LineWidth',1.5); end % Note f2 (lens+film MTF) and fscan nominally vary between 0 and 1. % fmax = max([.5 max(abs(f2(1:ldisp)-.5)) max(abs(fscan(1,1:ldisp)-.5))]); % Norml. to 0.5. fmax = max([.5 max(abs(f2(1:ldisp)-.5))]); % Norml. to 0.5. loglog(fq1,10.^((real(f2(1:ldisp)) -.5)/fmax+1),'m-'); fmax = max([.5 max(abs(fscan(1,1:ldisp)-.5))]); % Norml. to 0.5. loglog(fq1,10.^((real(fscan(1,1:ldisp))-.5)/fmax+1),'r-', 'LineWidth',1.5); plot([2 200],[10 10],'r--'); plot([2 200],[50 50],'b:'); hold off; ax = axis; ax(1) = ymin; ax(2) = ymax; % ax(3) = 1; % old ax(3) = 1; ax(4) = max([100 max(100*tfrfn) max(100*tfrtot)]); axis(ax); xlabel(xlblm); ylabel('MTF %, amplitude'); end % SEQUENCE PLOT figure; subplot('Position',[.01 .115 .98 .87]); image(255*ypp ); axis off; colormap(cmap); imwrite(ypp,'MTFcurve_image_3.tif','tif'); ypt = lv2; htxt = text(ldisp/30,ypt,['Original bands']); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold') if (nargin>=3) ypt = ypt+lvon; htxt = text(ldisp/30,ypt,['Lens only: flens = ' num2str(flens,3) ... '; lord = ' num2str(lord,2)]); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold'); if (f50>eps & f50<999) ypt = ypt+lvon; htxt = text(ldisp/30,ypt,['Film only: f50 = ' num2str(f50,3) ... '; fboost = ' num2str(fboost,3)]); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold'); ypt = ypt+lvon; htxt = text(ldisp/30,ypt,'Film + lens'); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold'); end elseif (f50>eps & f50<999) % Film only; no lens. ypt = ypt+lvon; htxt = text(ldisp/30,ypt,['Film: f50 = ' num2str(f50,3) ... '; fboost = ' num2str(fboost,3)]); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold'); end if (nargin>=5) ypt = ypt+lvon; htxt = text(ldisp/30,ypt,['Digitizer: ' num2str(dscan,4) ... ' dpmm = ' num2str(dscan*25.4,4) ' dpi; sinc\^' num2str(sincpwr,2)]); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold'); end if (nargin>=7) ypt = ypt+lton; htxt = text(ldisp/30,ypt,['Sharpen: ' num2str(ksharp,3)]); set(htxt,'Color',[1 .2 0],'Fontsize',10,'FontWeight','bold'); end subplot('Position',[.01 .11 .98 .005]); loglog(fq1,ones(size(fq1)),'k-'); ax = axis; ax(1) = ymin; ax(2) = ymax; axis(ax); xlabel(xlblm); fprintf('%s',7); % Ring bell. function y=sinc(x) %SINC Sin(pi*x)/(pi*x) function. y=ones(size(x)); i=find(x); y(i)=sin(pi*x(i))./(pi*x(i));