Matlab Code
Here is videotaped class I taught that covers the use of "f-mins" for curve fitting and a few other helpful tricks. It's not edited so it's long and boring but nice if these are the tricks you need! Check it out….
Spectrometer Calibration
This page contains all the necessary code to calibrate a Raman spectrometer. You will need a spectrometer capable of acquiring a spectrum that is a string of numbers, each the intensity at a particular wavelength and a calibration standard such as a Raman scattering target. The example given here uses a 785 nm LASER and Acetominophen standard but with a bit of modification, this technique should be able to work on emission standards such as Xenon or Argon lamps or work with any LASER wavelength.
Take a look at the Matlab code by clicking on this link.
First, download all the following files into one folder on your computer. The run the Matlab script "Run_n_show_result.m" This will show you the calibration on our system. Then you can replace the spectra with your own and modify the Matlab script accordingly to calibrate your spectrometer.
Abberations When Focusing Through an Optical Window
AbbCube.m simulates focusing through a 1-inch cube beam-splitter. The user is incouraged to first view the big picture by running the simulation as is but then set the zoom feature on line 27 to Ò1Ó to see what is happening at the focus where the aberration occurs.
AbbPlate.m simulates focusing through a thin pellicle beamsplitter at 45 degrees. The zoom settings are all at the very end of the program and the user is encouraged to play with them to see different scales in the simulation.
Source code in Matlab:
AbbCube.m
% AbbCube.m Dan Gareau 6-25-07 % This program finds the abberation caused by focusing through a % thick optical window. The picture drawn will be the entire view % unless the user sets the zoom feature (line 27) to 1. clear all close all Nrays = 6; f = 100 % mm focal length d = 10; % mm lens diameter NA = d/(2*f); % - numerical aperture of focus n1 = 1; % - refractive index n2 = 1.52; % - refractive index (window) n3 = 1; % - refractive index pos = 50; % mm front edge position of optical window t = 25.4; % mm window thickness shift = (n2-1)*t/n2; % P. 101 Ch. 4 prisms and mirrors shift = t*(1-n1/n2); % mm shift of focus with window inserted LA = t*sqrt((n3^2-NA^2)/(n2^2-NA^2))-n3/n2*t; hh = d/2; % mm height of lens zoom = 0; % zoom in to new focus to see the abberations for i = 1:Nrays h(i) = i/Nrays*hh; figure(1) plot([0 f],[h(i) 0],'k--') hold on plot([0 f],[-h(i) 0],'k--') theta1(i) = atan(h(i)/f); plot([0 pos],[h(i) (h(i) - tan(theta1(i))*pos)],'k-') plot([0 pos],[-h(i) -(h(i) - tan(theta1(i))*pos)],'k-') end % plot the optical window front surface plot([pos pos],[-hh hh],'k-') plot([f f],[-hh/3 hh/3],'k--') plot([(f+shift) (f+shift)],[-hh/3 hh/3],'k--') plot([(f+shift-LA) (f+shift-LA)],[-hh/3 hh/3],'k--') plot([f (f+shift)],[hh/4 hh/4],'k--') text(f-(shift/4), hh/2.4,sprintf('s = %1.1f mm',shift)) % plot the optical window other surface plot([(pos+t) (pos+t)],[-hh hh],'k-') text(pos + t*0.2,hh*0.90,sprintf('n = %1.2f',n2),'fontsize',16) text(pos - t*0.8,hh*0.90,sprintf('n = %1.2f',n1),'fontsize',16) text(pos + t*1.2,hh*0.90,sprintf('n = %1.2f',n1),'fontsize',16) % label the windothickness plot([pos (pos+t)],0.7*[hh hh],'k--') text(pos*1.05,0.75*hh,sprintf('t = %2.1f mm',t)) for i = 1:Nrays Yinc(i) = h(i) - pos*tan(theta1(i)); % y position of beam incident on window theta2(i) = asin(n1/n2*sin(theta1(i))); Yexit(i) = Yinc(i) - t*tan(theta2(i)); % y position of beam exiting window % plot the beam in the optical window n2 plot([pos (pos + t)],[Yinc(i) Yexit(i)],'k-') plot([pos (pos + t)],-[Yinc(i) Yexit(i)],'k-') c(i) = Yexit(i)/tan(theta1(i)); final(i) = pos + t + c(i); % plot the beam exiting the wondow to focus plot([(pos + t) final(i)],[Yexit(i) 0],'k-') plot([(pos + t) final(i)],[-Yexit(i) 0],'k-') end xlabel('z [mm]','fontsize',18) ylabel('y [mm]','fontsize',18) if zoom == 1; center = mean(final); range = 1.3*(center - min(final)); axis([ (center - 2*range) (center + 2*range) -range*0.2 range*0.2]) plot([(f+shift-LA) (f+shift)],[range*0.16 range*0.16],'k--') text(f+shift-LA*0.35, range*0.17, sprintf('LA = %1.0f µm', abs(LA*1000))) end set(gca,'fontsize',18)
AbbPlate.m
% Abberation.m % dagonal window clear all close all Nrays = 5; f = 100; % mm focal length d = 10; % mm lens diameter NA = d/(2*f); % - Numerical Aperture n1 = 1; % - refractive index n2 = 1.51; % - refractive index (window) n3 = 1; % - refractive index pos = 50; % mm front edge position of optical window t = 0.2; % mm window thickness ang = 45; % deg angle of sheet beamsplitter ang = pi*ang/180; % convert to radians hh = d/2; % mm height of lens dx = t*sin(ang); dy = t*cos(ang); V = (n2 - 1)/(n3 - n1); % Abbe V number P. 102 Ch 4 prisms & mirrors ang0 = 0; % initial angle of window before slanting % mm lateral displacement of axial beam D = -t*(n2-1)/n2; % small angle approximation (not too good) D = t*sin(ang0 - ang)/cos(ang); % mm lateral displacement of axial beam D = t*sin(ang)*(1-cos(ang)/cos(ang0)); % mm lateral displacement of axial beam % Draw Beamsplitter figure(1) plot([pos (pos + hh*tan(ang))],[0 hh],'k-') hold on plot([(pos - hh*tan(ang)) pos],[-hh 0],'k-') Ht = t/sin(ang); plot([(pos + Ht) (pos + hh*tan(ang) + Ht)],[0 hh],'k-') plot([(pos - hh*tan(ang) + Ht) (pos + Ht)],[-hh 0],'k-') xfinal = f*1.1; for i = 1:(2*Nrays)+1 ii = i - Nrays; if abs(ii) > 0 h(i) = ii*hh/Nrays; theta1(i) = atan(h(i)/f); y(i) = (h(i)/tan(theta1(i))-pos) / (1/tan(theta1(i))+ tan(ang)); x(i) = (h(i) - y(i))/tan(theta1(i)); plot([0 f],[h(i) 0],'k--') plot([0 x(i)],[h(i) y(i)],'k-') theta2(i) = pi/2 - ang - theta1(i); % angle of incidence to glass normal theta3(i) = asin(n1/n2*sin(theta2(i))); % angle of transmission into window l = t*tan(theta3(i)); ddx = t*tan(theta3(i))*cos(ang); ddy = t*tan(theta3(i))*sin(ang); y3(i) = y(i) - dy + ddy; x3(i) = x(i) + dx + ddx; plot([x(i) x3(i)],[y(i) y3(i)],'k-') y4(i) = y3(i) - (xfinal-x3(i))*tan(theta1(i)); plot([x3(i) xfinal],[y3(i) y4(i)],'k-') end end plot([0 xfinal],[D D],'k--') zoom1 = 1; % zoom in to new focus to see the abberations if zoom1 == 1; deltafactor = (t*n2)*0.8; deltafactory = (t*n2)*0.3; ctrx = f ; axis([ctrx-deltafactor ctrx+deltafactor -deltafactory 0.4*deltafactory ]) %plot([(f+shift-LA) (f+shift)],[range*0.16 range*0.16],'k--') %text(f+shift-LA*0.35, range*0.17, sprintf('LA = %1.0f µm', LA*1000)) end zoom2 = 0; % zoom in to new focus to see the abberations if zoom2 == 1; axis([100.0011 100.0014 -8e-4 -7.4e-4]) end zoom3= 0; % zoom in to new focus to see the abberations if zoom3 == 1; axis([48 53 -4 4]) axis off end %axis([0 120 -6 6]) set(gca, 'fontsize',18) xlabel('z [mm]') ylabel('y [mm]') %axis equal
The results from these simulations were used in the following:
Gareau D.S., Abeytunge S., Rajadhyaksha M., Full-pupil versus divided-pupil confocal line-scanners for reflectance imaging of human skin in vivo, Proc SPIE, 6443-31, 2007
Lens Design for Optical Window Focusing Correction
The program contained in this folder determines the correct launch angles for rays to focus through
an optical window. This might be a cover slip that holds a sample onto microscope slide. The code
works by creating a look up table for rays traced from the focus to the focusing optic, then sampling
the table to draw the forward rays. Master.m has many input variables to specify the geometry that
the user wishes to implement. The creation of the lookup table is done by the program called
CreateLookup.m and it is computationally demanding since many rays must be traced. The more rays
that are traced the better the program works in that the focus is never perfect but approximates focusing
to a point with more rays traced. Therefore, the user should set the variable Nrays to be as large as
possible and make sure that the focusing is acceptable. Using the current values, Nrays = 10,000 is
sufficient to keep the rays focusing to within 1 um of eachother and 100,000 rays gets the rays to
focus to within 0.1 um.
Happy focusing! --Dan
Source code in Matlab:
CreateLookup.m
% Abberation.m hh = d/2; % mm height of lens NA = n1*sin(atan(hh/f)) % [-] Numerical App. y3 = zeros(Nrays,1); th3 = zeros(Nrays,1); outY = zeros(Nrays/10,1); outTH = zeros(Nrays/10,1); % trace from focus to lens surface for i = 1:Nrays th1 = asin(NA)*i/Nrays;% * 180/pi; th2 = asin(n1/n2*sin(th1)); % Snell's baby! th3(i) = asin(n2/n3*sin(th2)); % Snell's baby! x1 = pos + t; x2 = pos; x3 = 0; y1 = tan(th1) * (f-x1); y2 = y1 + tan(th2)*t; y3(i) = y2 + tan(th3(i))*pos; if ifplot == 1 figure(1) plot([x1 f],[y1 0],'r-') hold on plot([x1 x2],[y1 y2],'r-') plot([x2 x3],[y2 y3(i)],'r-') end end if ifplot == 1 xlabel('z [mm]','fontsize',18) ylabel('y [mm]','fontsize',18) set(gca,'fontsize',18) end Nper = Nrays/10; for iii = 1:Nrays/Nper i = iii*100; outY(iii) = hh/(Nrays/Nper)*iii; for ii = 1:Nrays if y3(ii) < outY(iii) outTH(iii) = th3(ii); end end end if ifplot == 1 figure(2) plot(outY,outTH*180/pi,'ko') xlabel('radius of launch from lens surface [mm]') ylabel('angle of launch from lens surface [deg]') end Nrays = length(outTH); save OUTlookup outY outTH f n1 n2 n3 pos t Nrays
PlotForward.m
n1f = n3; %Reverse refractive indices to go forward to focus n2f = n2; n3f = n1; figure(3);clf for i = 1:Nrays th1 = outTH(i); th2 = asin(n1f/n2f*sin(th1)); % Snell's baby! th3 = asin(n2f/n3f*sin(th2)); % Snell's baby! plot([0 pos],[outY(i) (outY(i) - tan(th1)*pos)],'k-') hold on plot([0 pos],[-outY(i) -(outY(i) - tan(th1)*pos)],'k-') y1 = outY(i) - pos*tan(th1); y2 = y1 - t*tan(th2); y3 = 0; x1 = pos; x2 = pos + t; x3 = pos + t + y2*tan(pi/2-th3); plot([x1 x2],[y1 y2],'k--') plot([x2 x3],[y2 y3],'k-') plot([x1 x2],[-y1 -y2],'k--') plot([x2 x3],[-y2 -y3],'k-') end plot([pos pos],[-max(outY) max(outY)],'k-') plot([(pos+t) (pos+t)],[-max(outY) max(outY)],'k-') xlabel('z [mm]','fontsize',18) ylabel('y [mm]','fontsize',18) set(gca,'fontsize',18)
Master.mk
% Master.m by Dan Gareau 6-25-07 % This program implements a ray trace using Snell's law to correctly focus % light through an oprical window of high refractive index clear all close all Nrays = 10000; % 10000 for 1 um artifical axial aberration, 100000 for 0.1um f = 3; % mm focal length d = 5.5; % mm lens diameter n1 = 1.34; % - refractive index n2 = 1.52; % - refractive index (window) n3 = 1.34; % - refractive index pos = 2; % mm front edge position of optical window t = 0.5; % mm window thickness ifplot = 1; % show the ray-trace from focus to obj lens CreateLookup % yields OUTlookup.MAT --> outY outTH f n1 n2 n3 pos t Nrays sprintf('... Done creating look up table for ray launch ...') clear all load OUTlookup PlotForward sprintf('... Done running the forward ray trace ...')
Feature Matching Mosaic Stitching
The program contained in this folder stitches a 3-by-3 mosaic together in Matlab
- download all the files and pictures below into the same folder
- run Master.m
- when prompted, click on one ofthe 9 .bmp image files
- when prompted, select the top left cluster (excluding one data point in the bottom right) do this by using the cross hairs to click once on the top left of the cluster ..... then click on the cluster's bottom right and hitting enter.
Source code in Matlab:
Master.m
% Master.m % Dan Gareau 2008 % This Program builds a seemless mosaic from a batch of images by finding % the relative positions via feature-matching. if 1 == 1 clear all close all global frame1 frame2 InitialGuessXXX InitialGuessYYY MosaicSize Variation Overlap frameX frameY tempDir wind Showfit Xa Xb Ya Yb %%%%%%%%%%%%%%%%%%%%%%%%% User Choices InitialGuessXXX = 574; % [px] lateral displacement of sequential image pair X InitialGuessYYY = 0; % [px] Y wind = 15; % Size of the window around acceptable neighborhood MosaicSize = 3; % The square mosic size is [MosaicSize] images wide Showfit = 1; % 1 = graph the fitting algorithm in motion, 0 = don't (20% faster) %%%%%%%%%%%%%%%%%%%%%%%%% Rock and Roll... tic; GetFrameFits % Fits for the x and y offesets for feature matching for all HORIZONTAL neighboring pair toc FlipEm % Flipps every even row of image offsets disp(sprintf('Now running FlipEm.m which reverses the order of sequential rows')) disp(sprintf('And Sniffer.m which detects statistically bad fits')) OffXinit = OffsetX; OffYinit = OffsetY; showstats sniffer % sniffs out the bad seeds, eronious fits number = 0; % init for i = 1:length(flags) if flags(i)>0 number = number + 1; % Pretty straight forward end end figure(1);clf plot(OffXinit,OffYinit,'k*') hold on plot(OffsetX,OffsetY,'ro') title('scatter plot of fits of image offsets') legend('Original Fits','Corrected Fits') xlabel('X offset [pix]') ylabel('Y offset [pix]') disp(sprintf('In this case, the number of eronious fits was %d out of %d',number,length(flags) )) warning off save output OffXinit OffYinit OffsetX OffsetY MosaicSize frameY frameX Showfit clear all close all load output tic; makerows % calls the fitting results and FRAMES to assemble and save ROWS toc end % debug clear all close all tic; global showfit Showfit = 1; alignrows % Fits for the x and y offesets for feature matching for desending rows toc; clear all close all disp(sprintf('Now assembling the final mosaic')) tic; load output load FinalResults BuildMosaic % calls the fitting results and ROWS to assemble and save MOSAIC toc figure(2);clf imagesc(mosaic) colormap gray
GetFrameFits.m
% GetFrameFits.m % Fits for the x and y offesets for featuremapping % for all HORIZONTAL neighboring pairs % Dan Gareau 2008 global InitialGuessXXX InitialGuessYYY frameX frameY tempDir Showfit % Prompt User for Input Image Files defImgLoadFolder = ''; [filename, tempDir] = uigetfile('*.bmp', ... 'Pick one of image files', fullfile(defImgLoadFolder,'*.bmp')); figList = dir(fullfile(defImgLoadFolder, '*.bmp')); % Sorting, first by the length of file name, then by alphanumerical order len = []; for i= 1 : 1 : length(figList) len(i) = length( figList(i).name ); end [len,idx] = sort(len); for i = 1:length(figList) figList2(i) = figList(idx(i)); end sprintf('Now getting x-y coordinates for sequential frame fits') k = 0; ResultCounter = 0; for j = 1:MosaicSize kk = -1; disp(sprintf('now fitting frame number %d of %d',(j-1)*MosaicSize+1,MosaicSize*MosaicSize)) for i = 1:MosaicSize k = (j-1)*MosaicSize+i; if mod(k,MosaicSize) > 0 ResultCounter = ResultCounter + 1; frame1 = imread(fullfile(tempDir, figList2(k).name)); frame2 = imread(fullfile(tempDir, figList2(k+1).name)); if i == 1 [frameY frameX] = size(frame1); end if Showfit == 1 figure(2) subplot(1,2,1) imagesc(frame1) axis equal colormap gray subplot(1,2,2) imagesc(frame2) axis equal colormap gray end offx = -InitialGuessXXX; % initial guess at offset x offy = InitialGuessYYY; % initial guess at offset y if mod(j,2) == 0 offx = InitialGuessXXX; % initial guess at offset x offy = InitialGuessYYY; % initial guess at offset y end start = [offy offx]; results = fminsearch('fit',start); OffsetX(ResultCounter) = results(2); OffsetY(ResultCounter) = results(1)*1e5; % VARIABLE FACTOR!!! end end end
makerows.m
% makerows.m % Dan Gareau 2008 global tempDir ffigList = dir(fullfile(tempDir, '*.bmp')); % Sorting, first by the length of file name, then by alphanumerical order len = []; for i= 1 : 1 : length(ffigList) len(i) = length( ffigList(i).name ); end [len,idx] = sort(len); for i = 1:length(ffigList) ffigList2(i) = ffigList(idx(i)); end for rownum = 1:MosaicSize clear prev deltaPOS cumsum Y1rel MaxFactorY newval SumFactorXX SumFactorX OffsetY OffsetX clear OffsetNum index RowSize load output disp(sprintf('now building row number %d of %d',rownum,MosaicSize)) %index is the index of the beginning (leftmost) frame in the currrent %row within the results file that has MosaicSize-1 frames per row index(1,1) = (rownum-1)*(MosaicSize-1) + 1; % SumfactorX is the difference between how wide the row is and how % wide the row would be if the frames were just placed end to end for iii = 1:MosaicSize-1 SumFactorXX(iii) = sum( OffsetX( index : index+iii-1 )- frameX ); end SumFactorX = SumFactorXX(length(SumFactorXX)); % cumsum, the cumulative sum is the Y-offset between the LAST frame in % the current row and the current frame Icumsum = 0; for iii = rownum*(MosaicSize-1):-1:index Icumsum = Icumsum + 1; cumsum(Icumsum,1) = -sum(OffsetY(iii:rownum*(MosaicSize-1))); end MaxFactorY = max(cumsum) - min(cumsum); % the biggest difference if max(cumsum) < 0 % if last frame in row is LOWEST frame MaxFactorY = min(cumsum); end if min(cumsum) > 0 % if last frame in row is HIGHEST frame MaxFactorY = max(cumsum); end MaxFactorY = abs(MaxFactorY); [A B] = max(cumsum); % A = y-offset max B = index of such % deltaPOS = difference between top of LOWEST frame and top of 1st frame C = length(cumsum) - B; deltaPOS = 0; for back = C:-1:1 deltaPOS = deltaPOS - OffsetY(back); end if cumsum(length(cumsum)) == max(cumsum) && max(cumsum) > 0 deltaPOS = 0; end if A < 0 deltaPOS = cumsum(length(cumsum)); end Y1rel = MaxFactorY + deltaPOS; % first picture's y-position clear merge1 merge1 = zeros(MaxFactorY+frameY+4, MosaicSize*frameX + SumFactorX+1) - 1; [NNY NNX] = size(merge1); for LocalFrameNum = 1:MosaicSize if LocalFrameNum == 1 if cumsum(length(cumsum)) == min(cumsum) && cumsum(length(cumsum)) < 0 Y1rel = 0; end prev = Y1rel; end LocalOffsetNum = LocalFrameNum - 1; OffsetNum = LocalFrameNum - 1 + (rownum-1)*MosaicSize-rownum+1; if mod(rownum,2) == 0 k = LocalFrameNum + (rownum-1)*MosaicSize; end if mod(rownum,2) ~= 0 k = (rownum)*MosaicSize - LocalFrameNum + 1; end AddFrame = imread(fullfile(tempDir, ffigList2(k).name)); for j = 1:frameY for i = 1:frameX if LocalFrameNum == 1 ix = i; iy = round(j + Y1rel); else ix = round(LocalOffsetNum*frameX + SumFactorXX(LocalOffsetNum)+ i); iy = round( j + prev + OffsetY(OffsetNum)); end if merge1(iy,ix) < 0 merge1(iy,ix) = AddFrame(j,i); end if merge1(iy,ix) >= 0 newval = mean([merge1(iy,ix) AddFrame(j,i)]); merge1(iy,ix) = newval; end end end if LocalFrameNum > 1 prev = prev + OffsetY(OffsetNum); end end % end within row if Showfit == 1 imagesc(merge1) axis equal colormap gray drawnow end [tempY tempX] = size(merge1); RowSize(rownum,1)=tempY; RowSize(rownum,2)=tempX; eval(['save row' num2str(rownum) ' merge1;']); end % end of rows save RowSize RowSize
alignrows.m
% alignrows.m % Dan Gareau 12-2007 load output global Showfit for i = 1:MosaicSize eval(['load row' num2str(i) ';']); eval(['row' num2str(i) ' = merge1;']); end figure(1) subplot(3,1,1) imagesc(row1) subplot(3,1,2) imagesc(row2) subplot(3,1,3) imagesc(row3) ResultCounter = 0; for j = 1:MosaicSize-1 disp(sprintf('now fitting row number %d of %d',j+1,MosaicSize)) clear frame1 clear frame2 global frame1 frame2 ResultCounter = ResultCounter + 1; eval(['frame1 = row' num2str(j) ';']); eval(['frame2 = row' num2str(j+1) ';']); [Ny Nx] = size(frame2); if Showfit == 1 figure(2) subplot(1,2,1) imagesc(frame1) axis equal colormap gray subplot(1,2,2) imagesc(frame2) axis equal colormap gray end offx = -4; % -4 initial guess at offset x offy = Ny*0.75;%0.75;%*0.7; % initial guess at offset y start = [offy offx]; results = fminsearch('fitROWS',start); OffsetXrows(ResultCounter) = results(2);% VARIABLE FACTOR!!! OffsetYrows(ResultCounter) = results(1); if j == MosaicSize-1 SizeLast = Ny; end end save FinalResults OffsetXrows OffsetYrows SizeLast
BuildMosaic.m
% BuildMosaic.m % Dan Gareau 2008 global Showfit mosaic = zeros(frameY*MosaicSize,frameX*MosaicSize) - 1; [Ny Nx] = size(mosaic); for LocalFrameNum = 1:MosaicSize eval(['load row' num2str(LocalFrameNum) ';']); [Nfy Nfx] = size(merge1); if LocalFrameNum == 1 iStart = Nx/2 - Nfx/2; jStart = 0; end for j = 1:Nfy for i = 1:Nfx ix = round(iStart + i); iy = round(jStart + j); if mosaic(iy,ix) < 0 mosaic(iy,ix) = merge1(j,i); end if mosaic(iy,ix) >= 0 && merge1(j,i) > 0 newval = mean([mosaic(iy,ix) merge1(j,i)]); mosaic(iy,ix) = newval; end end end if LocalFrameNum < MosaicSize iStart = iStart + OffsetXrows(LocalFrameNum); jStart = jStart + OffsetYrows(LocalFrameNum); end if Showfit == 1 figure(1);clf imagesc(mosaic) axis equal colormap gray drawnow end end % end within row mosaic = uint8(mosaic); imwrite(mosaic,'TaylorStitch.BMP','BMP')
fit.m
% fit.m % Dan Gareau 2008 function err = fit(start) global frame1 frame2 Showfit [nny nnx] = size(frame1); offy = round(start(1)*1e5); % VARIABLE FACTOR!!! offx = round(start(2)); clear merge1 clear merge2 clear merged merge1 = zeros(nny+abs(offy),nnx+abs(offx)); merged = merge1; merge1 = merge1 - 1; [nnny nnnx] = size(merge1); merge2 = merge1; if (offx > 0) && (offy > 0) % adding to the lower right merge1(1:nny,1:nnx) = frame1; merge2(offy+1:nnny,offx+1:nnnx) = frame2; end if (offx > 0) && (offy < 0) % adding to the upper right merge1(abs(offy)+1:nnny,1:nnx) = frame1; merge2(1:nny,offx+1:nnnx) = frame2; end if (offx < 0) && (offy > 0) % adding to the lower left merge1(1:nny,abs(offx)+1:nnnx) = frame1; merge2(offy+1:nnny,1:nnx) = frame2; end if (offx < 0) && (offy < 0) % adding to the upper left merge1(abs(offy)+1:nnny,abs(offx)+1:nnnx) = frame1; merge2(1:nny,1:nnx) = frame2; end if (offx > 0) && (offy == 0) merge1(1:nnny,1:nnx) = frame1; merge2(1:nny,offx+1:nnnx) = frame2; end if (offx < 0) && (offy == 0) merge1(1:nny,abs(offx)+1:nnnx) = frame1; merge2(1:nnny,1:nnx) = frame2; end err = 0; % initialize count = 0; for i = 1:nnnx for j = 1:nnny if (merge1(j,i) < 0) && (merge2(j,i) >= 0) merged(j,i) = merge2(j,i); end if (merge1(j,i) >= 0) && (merge2(j,i) < 0) merged(j,i) = merge1(j,i); end if (merge1(j,i) >= 0) && (merge2(j,i) >= 0) merged(j,i) = (merge1(j,i)+merge2(j,i))/2; err = err + abs(merge1(j,i)-merge2(j,i)); count = count + 1; end end end err = err/count; if offx > nnx err = err + 1e12; end if Showfit == 1 figure(3) imagesc(merged) axis equal colormap gray drawnow end
fitROWS.m
% fitROWS.m % Dan Gareau 2008 function err = fitROWS(start) global frame1 frame2 Showfit [nny1 nnx1] = size(frame1); [nny2 nnx2] = size(frame2); offy = round(start(1)); offx = round(start(2));%*1e5% VARIABLE FACTOR!!! clear merge1 clear merge2 clear merged if nnx1 >= nnx2 merge1 = zeros(nny2+offy,nnx1+abs(offx)); end if nnx1 < nnx2 merge1 = zeros(nny2+offy,nnx2+abs(offx)); end merged = merge1; merge1 = merge1 - 1; [nnny nnnx] = size(merge1); merge2 = merge1; if offx > 0 % adding to the lower right merge1(1:nny1,1:nnx1) = frame1; merge2(nnny-nny2+1:nnny,nnnx-nnx2+1:nnnx) = frame2; end if offx < 0 % adding to the lower left merge1(1:nny1,nnnx-nnx1:nnnx-1) = frame1; merge2(offy+1:nnny,1:nnx2) = frame2; end if offx == 0 % adding to the lower left merge1(1:nny1,1:nnx1) = frame1; merge2(offy+1:nnny,1:nnx2) = frame2; end err = 0; % initialize count = 0; for i = 1:nnnx for j = 1:nnny if (merge1(j,i) < 0) && (merge2(j,i) >= 0) merged(j,i) = merge2(j,i); end if (merge1(j,i) >= 0) && (merge2(j,i) < 0) merged(j,i) = merge1(j,i); end if (merge1(j,i) >= 0) && (merge2(j,i) >= 0) merged(j,i) = (merge1(j,i)+merge2(j,i))/2; err = err + abs(merge1(j,i)-merge2(j,i)); count = count + 1; end end end if count == 0 count = 1; end err = err/count; if err == 0 err = 1e12; end if Showfit == 1 figure(3) imagesc(merged) axis equal colormap gray drawnow end
FlipEm.m
% FlipEm.m % Dan Gareau 2008 % Flipps every even row of image offsets for i = 1:MosaicSize if mod(i,2) ~= 0 iStart = 1+(MosaicSize-1)*(i-1); iStop = iStart + MosaicSize - 2; tempY = OffsetY(iStart:iStop); tempX = OffsetX(iStart:iStop); for ii = 1:MosaicSize-1 OffsetY(iStart+MosaicSize-1-ii) = -tempY(ii); OffsetX(iStart+MosaicSize-1-ii) = -tempX(ii); end end end
showstats.m
% showstats.m global Xa Xb Ya Yb figure(31);clf plot(OffXinit,OffYinit,'k*') hold on %plot(OffsetX,OffsetY,'ro') title('pick correct fit cluster region') %legend('Original Fits','Corrected Fits') xlabel('X offset [pix]') ylabel('Y offset [pix]') coord = ginput; Xa = coord(1,1); Xb = coord(2,1); Ya = coord(2,2); Yb = coord(1,2);
sniffer.m
% sniffer.m % Dan Gareau 2008 global Xa Xb Ya Yb Xa Xb Ya Yb global wind MMMoffY = (Ya + Yb)/2;%median(OffsetY); MMMoffX = (Xa + Xb)/2;%median(OffsetX); STDoffY = (Yb-Ya)/2;%(std(OffsetY); STDoffX = (Yb-Ya)/2;%std(OffsetX); flags = zeros(length(OffsetY),1); % init, if outlier, flag = 1 % Detect outliers outside offset results neighborhood for i = 1:length(OffsetY) if OffsetY(i) > MMMoffY + wind | OffsetY(i) < MMMoffY - wind | OffsetX(i) > MMMoffX + wind | OffsetX(i) < MMMoffX - wind %if OffsetY(i) > Yb | OffsetY(i) < Ya | OffsetX(i) > Xb | OffsetX(i) < Xa flags(i) = 1; end end resultcounter = 0; summX = 0; summY = 0; for i = 1:length(OffsetY) % find mean of acceptable neighborhood if flags(i) == 0 resultcounter = resultcounter + 1; summX = summX + OffsetX(i); summY = summY + OffsetY(i); end end meanY = summY/resultcounter; meanX = summX/resultcounter; for i = 1:length(OffsetY) if flags(i) == 1 OffsetY(i) = meanY; OffsetX(i) = meanX; end end