function [dgr dr dgb db] = show_tca(file) % experimental tool to display and estimate tca correction coefficients, % based on a hugin project file that specifies control points between % r and g, and g and b channel. % % It will read the specified pto file, extract the distortion % correction values and control points. A graph, with the % scaling factor over the distance from the image center will % be plotted. % % Additionally, a correction polynomial is estimated useing these % distances. This is better than the optimized correction polynomial, % because PTOptimizer minimizes the distance between the two points, % and this script minimizes the difference between the distances % from the center. % % Licensed under the GPL version 2 by Pablo d'Angelo % % Changes: % 2006-11-11 do not use pcregexp anymore, should work with standard octave % installations. % plot1 = 1; plot2 = 1; save_plots=0; % read control points from file f = fopen(file,'r'); red = []; blue = []; ptodist = []; ptov = []; while ~ feof(f) line = fgetl(f); if (length(line) == 0) continue; end % new code to parse i line without pcregexp, which seems to behave differently % with various octave versions if (line(1) == 'i') str = line(3:end); imsize = [0 0]; distc = [0 0 0]; v = 0; while (length(str) > 0) [t str] = strtok(str); if t(1) == 'w'; imsize(1) = str2num(t(2:end)); end if t(1) == 'h', imsize(2) = str2num(t(2:end)); end if t(1) == 'a', distc(1) = str2num(t(2:end)); end if t(1) == 'b', distc(2) = str2num(t(2:end)); end if t(1) == 'c', distc(3) = str2num(t(2:end)); end if t(1) == 'v', v = str2num(t(2:end)); end end ptodist = [ptodist ; distc ]; ptov = [ptov ; v]; end % extract image size % this code works from some versions of octave, with octave-forge %s = pcregexp('^i.* w(\\d+) .*h(\\d+) .* a([-\\w\\.]+) b([-\\w\\.]+) c([-\\w\\.]+) .* v([\\w\\.]+)', line); %if size(s,1) == 7 % imsize = [str2num(line(s(2,1):s(2,2))), str2num(line(s(3,1):s(3,2)))]; % distc = [str2num(line(s(4,1):s(4,2))), str2num(line(s(5,1):s(5,2))), str2num(line(s(6,1):s(6,2))) ]; % ptodist = [ptodist ; distc]; % ptov = [ ptov ; str2num(line(s(7,1):s(7,2))) ]; %end % c n0 N1 x20 y2724 X20.6432 Y2723.36 t0 if (line(1) == 'c') t = sscanf(line, 'c n%d N%d x%f y%f X%f Y%f t%d'); if t(1) == 1 a = 1; b = 2; ai = 3; bi = 5; elseif t(2) == 1 a = 2; b = 1; ai = 5; bi = 3; else continue; end if t(b) == 0, % red channel v = [ t(ai:ai+1)' t(bi:bi+1)' ]; red = [ red ; v]; end if t(b) == 2, v = [ t(ai:ai+1)' t(bi:bi+1)' ]; blue = [ blue ; v]; end end end fclose(f); % calculate distortion parameters estimated by PTOptimizer scale = ptov(2) ./ ptov; ptdist = ones(3,1) - sum(ptodist,2); ptdist = [ptodist ptdist]; ptdist = ptdist .* [scale.^4 scale.^3 scale.^2 scale]; center = imsize / 2; rfactor = min(imsize) / 2; maxr = norm(imsize/2); [dr, dgr] = dist(red, center); [db, dgb] = dist(blue, center); disp('correction parameters read from pto file:') disp(sprintf(' -r %.7f:%.7f:%.7f:%.7f', ptdist(1,:))); disp(sprintf(' -b %.7f:%.7f:%.7f:%.7f', ptdist(3,:))); % fit own correction function % fit polynom to the function here coefr2 = polyfit(dgr/rfactor, dgr./dr,3); coefb2 = polyfit(dgb/rfactor, dgb./db,3); disp('new fit, based on distance to image center:') disp(sprintf(' -r %.7f:%.7f:%.7f:%.7f', coefr2)); disp(sprintf(' -b %.7f:%.7f:%.7f:%.7f', coefb2)); if plot1, figure plot(dgr/rfactor, dgr./dr, 'r+'); hold on; plot(dgb/rfactor, dgb./db, 'b+'); xlabel('distance from center'); ylabel('scale factor'); % plot correction read from pto file x = (1:50:maxr)/rfactor; plot(x, polyval(ptdist(1,:), x), 'r-'); plot(x, polyval(ptdist(2,:), x), 'g-'); plot(x, polyval(ptdist(3,:), x), 'b-'); plot(x, polyval(coefr2,x), 'r-@*'); plot(x, polyval(coefb2,x), 'b-@*'); %legend('red channel', 'blue channel', 'PT red', 'PT green', 'PT blue', 'new red', 'new blue', 3); if save_plots print('corr_curves.eps','-color', '-F:18'); end end % calculate distance perpendicular to ray from image center distr = red(:,1:2) - red(:,3:4); distr = sqrt(sum(distr.^2,2)); dr_perp = sqrt(distr.^2 - (abs(dr-dgr)).^2); if plot2, figure plot(dgr, dr_perp,'r*'); hold on; plot(dgr, abs(dr-dgr),'bo'); xlabel('distance from center (pixels)'); ylabel('distance between green and red channel (pixels)'); legend('red: tangential distance', 'blue: sagittal distance'); if save_plots print('distance.eps','-color','-F:18'); end end function [dc, dg] = dist(a, center) % calculate distance between the control points.. dchannel = a(:,1:2) - repmat(center, size(a,1),1); dgreen = a(:,3:4) - repmat(center, size(a,1),1); % calculate difference of distance from center dg = sqrt(sum(dgreen.^2,2)); dc = sqrt(sum(dchannel.^2,2)); distance = dg - dc;