// colorfind.cpp // Porter's program for cutting out colored squares // modified by DS 3/8/09 // static char *usage ="\n usage: %s in.png cutsquares.png [marked-in.png]\n"; #include "imageLib.h" #include "math.h" #define VERBOSE 1 #define ROUND(x) ((x) >= 0? ((int)((x) + .5)) : ((int)((x) - .5))) //Pulls the colors from the color checker and makes a new image with just the color squares void colorfind(CByteImage src, CByteImage& dst) { CShape sh = src.Shape(); int w = sh.width, h = sh.height, nB = sh.nBands; int ncols; //Number of squares ncols the checker int nrows; //number of squares vertically on the checker float aspect = (float) w/h; float trimfactor; float colorfract; // size of color patch as fraction of full square //Aspect ratio determines which checker is assumed if(aspect > 1.46){ // 24 checker ncols = 6; nrows = 4; trimfactor = .005; colorfract = .75; } else{ // 140 checker ncols = 14; nrows = 10; trimfactor = .002; colorfract = .55; } //Comment on method here float xlost = w*trimfactor; float s = (w+2*xlost)/ncols ; float center = s/2; int r = ROUND(colorfract * center); if (r < 1) r = 1; // make sure radius doessn't get too small int d = 2*r + 1; // diameter, i.e., square size in cropped image int firstCenterx = ROUND(center-xlost); float ylost = (nrows * s - h) / 2; //printf("xlost = %.1f, ylost = %.1f\n", xlost, ylost); int firstCentery = ROUND(center-ylost); //Create a new image shape with the appropriate size CShape sh2(d*ncols, d*nrows, nB); dst.ReAllocate(sh2); //Iterates over each square, and then each pixel in the square, and writes to the new image, and clear the pixel in the source for(int j = 0; j < nrows; j++){ for(int i = 0; i < ncols; i++){ int xCenter = firstCenterx + ROUND(i*s); int yCenter = firstCentery + ROUND(j*s); for(int y = - r; y <= r;y++){ for(int x = -r; x <= r; x++){ int srcx = xCenter + x; int srcy = yCenter + y; int dstx = i * d + x + r; int dsty = j * d + y + r; for(int b = 0; b < nB; b++){ // copy pixel dst.Pixel(dstx, dsty, b) = src.Pixel(srcx, srcy, b); // draw border if (b < 3 && // don't change alpha channel (x == - r || y == - r || x == r || y == r)) { src.Pixel(srcx, srcy, b) = src.Pixel(xCenter, yCenter, b) < 128 ? 255 : 0; } } } } } } } int main(int argc, char *argv[]) { try { if (argc < 3) throw CError(usage, argv[0]); CByteImage im1, im2; ReadImageVerb(im1, argv[1], VERBOSE); CShape sh = im1.Shape(); colorfind(im1, im2); WriteImageVerb(im2,argv[2], VERBOSE); if (argc > 3) WriteImageVerb(im1,argv[3], VERBOSE); } catch (CError &err) { fprintf(stderr, err.message); fprintf(stderr, "\n"); return -1; } return 0; }