#!/usr/bin/octave -qf % ------------------------------------------------------------------------------------- % PRECONDITIONS % THIS SCRIPT NEEDS NUMBER OF IMAGES, IMAGE DIMENSIONS, OFFSETS(x and y), ANGLES % the offsets and angles above are absolute values, i.e. relative to image 1. % POSTCONDITIONS % THIS SCRIPT OUTPUTS initial x,y offsets and width,height for cropping for every image % you can set enable_plot to 1 to show a preview of the cropping region % ------------------------------------------------------------------------------------- clear all close all enable_plot=0; function common = is_common(x,y,from_1_to,N,sizex,sizey) % this funtion remaps a point from base image space back to EACH original image space and checks if it lies within the boundaries of sizex,sizey p=[x y 1]; remapped=zeros(N,3); for i=1:N remapped(i,:)=p*from_1_to{i}; end % if an of the x>sizex or any of the y>sizey we are out of bounds if (any(remapped(:,2)>sizey) | any(remapped(:,1)>sizex)) common=0; else common=1; end endfunction % preliminary check of input arguments if (nargin == 0) disp('error, script called without arguments!'); exit(1); end % get num of images from first argument N=sscanf(argv{1},'%d'); % input parameters are in the form: $numimages $width $height @xShift @yShift @rRotation num_tot_arg=1+1+1+(N*3); if (nargin ~= num_tot_arg) disp('error in input arguments, check how hdrprep feeds this script!'); exit(1); end % read image dimensions sizex=sscanf(argv{2},'%d'); sizey=sscanf(argv{3},'%d'); % read X shits % read Y shits % read rotations for i=1:N shift_x{i}=sscanf(argv{3+i},'%f'); shift_y{i}=sscanf(argv{3+(N)+i},'%f'); angle{i}=sscanf(argv{3+(N)+(N)+i},'%f'); end % rotation only matrices and translation only matrices for i=1:N rotation_for{i}=[ cos(angle{i}*pi/180) -sin(angle{i}*pi/180) 0; sin(angle{i}*pi/180) cos(angle{i}*pi/180) 0; 0 0 1]; translation_for{i}=[ 1 0 0; 0 1 0; shift_x{i} -shift_y{i} 1]; %opposite sign for Ty! end % another shift to move the 4 corners around the center (0,0) trasl_123=[1 0 0; 0 1 0; -sizex/2 -sizey/2 1]; % 4 corner points down_left=[0 0 1]; down_right=[sizex 0 1]; up_right=[sizex sizey 1]; up_left=[0 sizey 1]; % tx * rot for i=1:N to_1_from{i}=trasl_123*rotation_for{i}*translation_for{i}; % direct mapping matrix from_1_to{i}=inv(to_1_from{i}); % inverse mapping matrix end % direct mapping into base image (number 1) space for i=1:N e_m{i}{1}=up_left*to_1_from{i}; e_m{i}{2}=up_right*to_1_from{i}; e_m{i}{3}=down_right*to_1_from{i}; e_m{i}{4}=down_left*to_1_from{i}; end wholeset=ones(N*4,3); %build "wholeset" data structure to find initial cropping area % wholeset's data structure: % x1 y1 1 %"1" is the id number for the first image % x2 y2 1 % x3 y3 1 % x4 y4 1 % x1 y1 2 % x2 y2 2 % x3 y3 2 % x4 y4 2 % ... % ... for i=1:N for p=1:4 %4 points wholeset(4*(i-1)+p,:) = [e_m{i}{p}(1) e_m{i}{p}(2) i]; end end % wholeset [Ms I]=sort(wholeset); % finding coordinates of innermost cropping rectangle. lx=wholeset(I( 0+size(I,1)/2,1 ),1); % left x rx=wholeset(I( 1+size(I,1)/2,1 ),1); % right x dy=wholeset(I( 0+size(I,1)/2,2 ),2); % down y uy=wholeset(I( 1+size(I,1)/2,2 ),2); % up y candidate_lx=lx; candidate_rx=rx; candidate_uy=uy; candidate_dy=dy; do % expand the 4 candidates by 1 pixel candidate_lx--; candidate_rx++; candidate_uy++; candidate_dy--; % until you exit "common" area i.e. the one shared by all the images until ( !(is_common(candidate_lx,candidate_uy,from_1_to,N,sizex,sizey)) || !(is_common(candidate_rx,candidate_uy,from_1_to,N,sizex,sizey)) || !(is_common(candidate_rx,candidate_dy,from_1_to,N,sizex,sizey)) || !(is_common(candidate_lx,candidate_dy,from_1_to,N,sizex,sizey)) ) % get back in line! ;) candidate_lx++; candidate_rx--; candidate_uy--; candidate_dy++; final_x=[candidate_lx candidate_rx candidate_rx candidate_lx candidate_lx]; final_y=[candidate_uy candidate_uy candidate_dy candidate_dy candidate_uy]; % OUTPUT: cropping WIDTH and HEIGHT printf('%f %f ', candidate_rx-candidate_lx,candidate_uy-candidate_dy); % base image's cropping OFFSETS X and Y printf('%f %f ', abs(e_m{1}{1}(1)-candidate_lx), abs(e_m{1}{1}(2)-candidate_uy)); % other images' cropping OFFSETS X and Y for i=2:N if (angle{i}<0) printf('%f %f ', abs(e_m{i}{1}(1)-candidate_lx), abs(e_m{i}{2}(2)-candidate_uy)); else printf('%f %f ', abs(e_m{i}{4}(1)-candidate_lx), abs(e_m{i}{1}(2)-candidate_uy)); end end if (enable_plot) % plot the four corners mapped in base image space for i=1:N mappedimage_x{i}=[e_m{i}{1}(1) e_m{i}{2}(1) e_m{i}{3}(1) e_m{i}{4}(1) e_m{i}{1}(1)]; mappedimage_y{i}=[e_m{i}{1}(2) e_m{i}{2}(2) e_m{i}{3}(2) e_m{i}{4}(2) e_m{i}{1}(2)]; plot(mappedimage_x{i},mappedimage_y{i},'3'); hold on; end % plot innermost cropping rectangle. innerx=[lx rx rx lx lx]; innery=[uy uy dy dy uy]; plot(innerx,innery,'2'); plot(final_x,final_y,'1'); pause; end