#! /bin/gawk -f # Last edited on 2003-04-07 12:55:17 by stolfi BEGIN{ usage = ( ARGV[0] " < INFILE > OUTFILE" ); abort = -1; # Takes a file with raw reference point data and outputs # a cleaned version, suitable for `source'ing into a script. # # The input may have lines of the form # # batch = BATCHNAME # Start of a new logical batch of images (which may not correspond to # any single batch directory). `BATCHNAME' is the name of the batch, which # is not used for anything. # mag = N # Sets the magnifying factor for all Image (pixel) coordinates that follow. # unit = N # Sets the unit for all Scene (actual) coords that follow to N millimeters. # pts = ( X1,Y1,Z1 X2,Y2,Z2 ... Xn,Yn,Zn ) # Scene (acual) coordinates of reference points, in current units. Note: # there should be no spaces around the commas. # img = IMGNAME # Specifies that image with filename IMGNAME is part # of the logical batch. This line may be followed by image # coordinates for its reference points (below). # ! ID H,V = ..... # Image coordinates (in pixels) of a reference point for the # current image. The {ID} identifies the point. The first four # points must be grid points and must have IDs of the form # {gridNN} where {NN = 00,01,02,03}. The rest of the line is in # the format of the data obtained with "xv"'s eyedropper; only # the {H,V} coordinates are used. The `V' axis points down # (0 at top line of image). The corresponding Scene coordinates # are taken from the {pts =} directive (above). # @ ID H V X Y Z # Same as the preceding line, except that the Scene coordinates # of the point are assumed to be {X,Y,Z}. # # Within a logical batch, if any image has no grid ref points # specified, it gets defaults from some preceding image in same batch. # Points other than grid points are not defaulted. # # The output file will contain one shell-like command for each image: # # process_image IMGNAME \ # H1 V1 X1 Y1 Z1 ID1 \ # ... \ # Hn Vn Xn Yn Zn IDn \ # eoi # # In addition, after all images of each batch, there will be a # command for the batch: # # process_batch BATCHNAME \ # IMGNAME1 \ # ... \ # IMGNAMEm \ # eob cur_batch = ""; cur_mag = 1; cur_unit = 1; cur_npts = 0; printf "# Created mechanically by cleanup-gridpoints\n"; printf "\n"; } (abort >= 0){ exit abort; } /^ *([#]|$)/{ next; } /^mag *= *[0-9.]+ *$/{ sub(/[=]/, " = ", $0); if (NF != 3) { data_error(("bad mag line \"" $0 "\"")); } cur_mag = $3; next; } /^unit *= *[0-9.]+ *$/{ sub(/[=]/, " = ", $0); if (NF != 3) { data_error(("bad unit line \"" $0 "\"")); } cur_unit = $3; next; } /^pts *= *[(].*[)] *$/{ sub(/[=]/, " = ", $0); sub(/[(]/, " ( ", $0); sub(/[)]/, " ) ", $0); if (NF < 5) { data_error(("bad pts line \"" $0 "\"")); } cur_npts = NF-4; split("", cur_pt_x); split("", cur_pt_y); split("", cur_pt_z); printf "pts = (" > "/dev/stderr"; for (k = 0; k < cur_npts; k++) { pt = $(4+k); if (pt !~ /^[0-9]+,[0-9]+,[0-9]+$/) { data_error(("invalid coordinates \"" pt "\" in \"pts\" line")); } split(pt,c,","); cur_pt_x[k] = cur_unit*c[1]; cur_pt_y[k] = cur_unit*c[2]; cur_pt_z[k] = cur_unit*c[3]; printf " %02d,%02d,%02d", cur_pt_x[k],cur_pt_y[k],cur_pt_z[k] > "/dev/stderr"; } printf ")\n" > "/dev/stderr"; next; } /^batch *= *[-a-z0-9A-Z\/]+ *$/{ sub(/[=]/, " = ", $0); if (NF != 3) { data_error(("bad batch line \"" $0 "\"")); } if (cur_batch != "") { flush_batch(); } init_batch(); cur_batch = $3; next; } /^img *= *[-a-z0-9A-Z\/]+ *$/{ sub(/[=]/, " = ", $0); if (NF != 3) { data_error(("bad img line \"" $0 "\"")); } cur_img = $3; if (cur_img in img_npts) { data_error(("repeated image \"" cur_img "\" in batch \"" cur_batch "\"")); } img_npts[cur_img] = 0; # Add image to list of images of this batch: batch_img[batch_nimgs] = cur_img; batch_nimgs++; next; } /^[!] *[A-Za-z][-A-Za-z0-9_./]* *[0-9]+[,] *[0-9]+ *[=]/{ gsub(/[,]/, " ",$0); gsub(/[=].*$/, "",$0); if (NF != 4) { data_error(("bad ref point line \"" $0 "\"")); } pt = $2; pt_h = cur_mag*$3; pt_v = cur_mag*$4; i = img_npts[cur_img]; if (i >= cur_npts) { data_error(("No Scene coordinates given for \"" pt "\"")); } save_ref_point(pt, pt_h, pt_v, cur_pt_x[i], cur_pt_y[i], cur_pt_z[i]); next; } /^[@] *[A-Za-z][-A-Za-z0-9_./]* *[-+]?[0-9.]+ *[-+]?[0-9.]+ *[-+]?[0-9.]+ *[-+]?[0-9.]+ *[-+]?[0-9.]+ *$/{ if (NF != 7) { data_error(("bad ref point line \"" $0 "\"")); } pt = $2; pt_h = cur_mag*$3; pt_v = cur_mag*$4; pt_x = unit*$5; pt_y = unit*$6; pt_z = unit*$7; save_ref_point(pt, pt_h, pt_v, pt_x, pt_y, pt_z); next; } function save_ref_point(pt,h,v,x,y,z, ipt) { ipt = img_npts[cur_img]; img_pt[ipt] = pt; img_npts[cur_img]++; # First four points must be grid reference points 00-03: if (ipt < 4) { if (pt != sprintf("grid%02d",ipt)) { data_error(("bad grid point id \"" pt "\"")); } default_img = cur_img; } if ((cur_img,pt) in img_pt_h) { data_error(("duplicated point \"" pt "\" in image")); } img_pt_h[cur_img,pt] = h; img_pt_v[cur_img,pt] = v; img_pt_x[cur_img,pt] = x; img_pt_y[cur_img,pt] = y; img_pt_z[cur_img,pt] = z; } // { data_error(("unrecognized line \"" $0 "\"")); } END { if (cur_batch != "") { flush_batch(); } } function init_batch( ) { default_img = ""; # Image that defines default img coords for grid pts. batch_nimgs = 0; # Number of images in current batch. split("", batch_img); # Names of images in current batch, [0..batch_nimgs-1]. # Per-image data: split("", img_npts); # `np == img_npts[img]' num of ref pts given for `img'. split("", img_pt); # `img_pt[0..np-1]' are the IDs of ref pts given for `img'. split("", img_pt_h); # `img_pt_h[img,id]' image H coords of ref pt `id'. split("", img_pt_v); # `img_pt_v[img,id]' image V coords of ref pt `id'. split("", img_pt_x); # `img_pt_x[img,id]' nominal X coords of ref pt `id'. split("", img_pt_y); # `img_pt_y[img,id]' nominal Y coords of ref pt `id'. split("", img_pt_z); # `img_pt_z[img,id]' nominal Z coords of ref pt `id'. } function flush_batch( iim,ipt,img,pt,img1) { for (iim = 0; iim < batch_nimgs; iim++) { img = batch_img[iim]; if (img_npts[img] == 0) { # Get grid points from default image: img1 = default_img; printf "defaulting %s from %s\n", img, img1 > "/dev/stderr"; for (ipt = 0; ipt < 4; ipt++) { pt = sprintf("grid%02d", ipt); img_pt[i] = pt; img_pt_h[img,pt] = img_pt_h[img1,pt] img_pt_v[img,pt] = img_pt_v[img1,pt] img_pt_x[img,pt] = img_pt_x[img1,pt] img_pt_y[img,pt] = img_pt_y[img1,pt] img_pt_z[img,pt] = img_pt_z[img1,pt] img_npts[img]++; } } else if (img_npts[img] < 4) { data_error(("incomplete grid point set for image \"" img "\"")); } printf "\n"; printf "process_image %s \\\n", img; for (ipt = 0; ipt < img_npts[img]; ipt++) { pt = img_pt[ipt]; printf " %6.1f %6.1f %6.1f %6.1f %6.1f %s \\\n", \ img_pt_h[img,pt], img_pt_v[img,pt], \ img_pt_x[img,pt], img_pt_y[img,pt], img_pt_z[img,pt], pt; } printf " eoi\n"; } printf "\n"; printf "process_batch %s \\\n", cur_batch; for (iim = 0; iim < batch_nimgs; iim++) { img = batch_img[iim]; printf " %s \\\n", img; } printf " eob\n"; } function data_error(msg) { printf "line %d: ** %s\n", FNR, msg > "/dev/stderr"; abort = 1; exit abort; }