%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MODULATION TRANSFER FUNCTION FROM EDGE % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % This does the following functions: % Find the position of the edge in the image % Using the edge position, find the distance of each point from the edge % Plot "distance vs signal" using all the points % Use a local weighted linear fit approach to average / smooth all the data % points to get a smooth edge spread function % Differentiate the results, and apply a little more smoothing to get the % point spread function % Perform the FFT % % In the source code, various settings can be changed relating to how % the data points are smoothed, what data ranges we work with etc. % % One big question is how to find the equation of the original line % properly - even a small error in this can lead to problems. % This script interpolates the data to 0.1 pixel resolution and finds the % point in each column where we're closest to the middle of the edge. % This means we're making good use of the intensity information. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Variables you need to set up beforehand: % InitialImage % InitialMask - 256*256 matrix. Any pixels you want masked should be set to % 0, others to 1 % SET THE PIXEL RANGE TO WORK WITH, IF NEEDED % This allows to to crop to the region around the edge % Planar uses Y 50-200. 3D should use Y 80-200 XMin=10; XMax=246; %YMin=50; %YMax=200; YMin=80; YMax=200; % Note that we should crop the image before processing: EdgeImage=InitialImage(YMin:YMax,XMin:XMax); Mask=InitialMask(YMin:YMax,XMin:XMax); [Ysize,Xsize] = size(EdgeImage); %%%%%%%%% MASKING BEFORE EDGE FINDING % For edge finding processes, we'll apply median filtering to the noisy % pixels so they don't throw off the results. FullFiltEdgeImage=medfilt2(EdgeImage); MaskFiltEdgeImage=EdgeImage; MaskFiltEdgeImage(~Mask)=FullFiltEdgeImage(~Mask); %%%%%%%%% EDGE FINDING % Now, we want to find the middle of the edge spread function in each % column of pixels. As a start point, need to actually find the range of % values MeanPixelVal=mean(MaskFiltEdgeImage(:)); % Histogram the pixel values % Assuming we have 1000s of counts, and at least 20000 pixels in each % region, then using 200 bins will give us reasonable precision and a % decent no of counts in the appropriate bins. "Bins" is array of X-values [ImageHist,bins] = hist(MaskFiltEdgeImage(:),200); figure; stairs(bins,ImageHist) % The histogram should have one peak above the mean and one below it. Find % them, and get the midrange HighHist=ImageHist.*(bins>MeanPixelVal); LowHist=ImageHist.*(binsDistMin) & (DistMicrons(y,x)=0); LSDist_pos=LineSpreadDistance(LineSpreadDistance>=0); % Find the positions closest to half maximum LSF_neg_DiffFromMid=LSF_neg-(PeakAmplitude./2); [LSF_neg_MidEdgeVal,LSF_neg_MidEdgeIndex]=min(abs(LSF_neg_DiffFromMid)); LSF_neg_MidEdgeVal; LSF_neg_MidEdgePos=LSDist_neg(LSF_neg_MidEdgeIndex) LSF_pos_DiffFromMid=LSF_pos-(PeakAmplitude./2); [LSF_pos_MidEdgeVal,LSF_pos_MidEdgeIndex]=min(abs(LSF_pos_DiffFromMid)); LSF_pos_MidEdgeVal; LSF_pos_MidEdgePos=LSDist_pos(LSF_pos_MidEdgeIndex) FullWidthHalfMaximum=LSF_pos_MidEdgePos-LSF_neg_MidEdgePos % Next, want a measure of the steepness of the rising and falling edges % Do this by finding the 20% to 80% rise and fall distance. [LSF_neg_val,LSF_neg_RisingEdgeIndex1]=min(abs(LSF_neg-0.2*PeakAmplitude)); LSF_RisingEdge1=LSDist_neg(LSF_neg_RisingEdgeIndex1) [LSF_neg_val,LSF_neg_RisingEdgeIndex2]=min(abs(LSF_neg-0.8*PeakAmplitude)); LSF_RisingEdge2=LSDist_neg(LSF_neg_RisingEdgeIndex2) LSF_RisingEdgeDist=LSF_RisingEdge2-LSF_RisingEdge1 %LSF_pos=LSF_pos(1:160); [LSF_pos_val,LSF_pos_FallingEdgeIndex1]=min(abs(LSF_pos-0.2*PeakAmplitude)); LSF_FallingEdge1=LSDist_pos(LSF_pos_FallingEdgeIndex1) [LSF_pos_val,LSF_pos_FallingEdgeIndex2]=min(abs(LSF_pos-0.8*PeakAmplitude)); LSF_FallingEdge2=LSDist_pos(LSF_pos_FallingEdgeIndex2) LSF_FallingEdgeDist=LSF_FallingEdge1-LSF_FallingEdge2 % Measure of variation in signal due to beam intensity etc LSFVariationSigma=std(LSF_pos((50/Interp_spacing):(100/Interp_spacing)))