bool LoadImageFile(const char *filename, CByteImage &image) { // Load the query image. printf("%s\n", filename); Fl_Shared_Image *fl_image = Fl_Shared_Image::get(filename); if (fl_image == NULL) { printf("TGA\n"); ReadFile(image, filename); return true; } else { printf("Not TGA\n"); CShape sh(fl_image->w(), fl_image->h(), 4); image = CByteImage(sh); // Convert the image to the CImage format. if (!convertImage(fl_image, image)) { printf("couldn't convert image to RGB format\n"); return false; } /* Set the alpha channel to 1 everywhere */ int w = sh.width; int h = sh.height; sh = image.Shape(); // printf("shape: %d, %d, %d\n", sh.width, sh.height, sh.nBands); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { image.Pixel(x, y, 3) = 255; } } return true; } }
void InstantiateConvolutions() { InstantiateConvolutionOf(CByteImage()); InstantiateConvolutionOf(CIntImage()); InstantiateConvolutionOf(CFloatImage()); }
/******************* TO DO 5 ********************* * BlendImages: * INPUT: * ipv: list of input images and their relative positions in the mosaic * blendWidth: width of the blending function * OUTPUT: * create & return final mosaic by blending all images * and correcting for any vertical drift */ CByteImage BlendImages(CImagePositionV& ipv, float blendWidth) { // Assume all the images are of the same shape (for now) CByteImage& img0 = ipv[0].img; CShape sh = img0.Shape(); int width = sh.width; int height = sh.height; int nBands = sh.nBands; // int dim[2] = {width, height}; int n = ipv.size(); if (n == 0) return CByteImage(0,0,1); bool is360 = false; // Hack to detect if this is a 360 panorama if (ipv[0].imgName == ipv[n-1].imgName) is360 = true; // Compute the bounding box for the mosaic float min_x = FLT_MAX, min_y = FLT_MAX; float max_x = 0, max_y = 0; int i; for (i = 0; i < n; i++) { CTransform3x3 &T = ipv[i].position; // BEGIN TODO // add some code here to update min_x, ..., max_y printf("TODO: %s:%d\n", __FILE__, __LINE__); // END TODO } // Create a floating point accumulation image CShape mShape((int)(ceil(max_x) - floor(min_x)), (int)(ceil(max_y) - floor(min_y)), nBands + 1); CFloatImage accumulator(mShape); accumulator.ClearPixels(); double x_init, x_final; double y_init, y_final; // Add in all of the images for (i = 0; i < n; i++) { // Compute the sub-image involved CTransform3x3 &M = ipv[i].position; CTransform3x3 M_t = CTransform3x3::Translation(-min_x, -min_y) * M; CByteImage& img = ipv[i].img; // Perform the accumulation AccumulateBlend(img, accumulator, M_t, blendWidth); if (i == 0) { CVector3 p; p[0] = 0.5 * width; p[1] = 0.0; p[2] = 1.0; p = M_t * p; x_init = p[0]; y_init = p[1]; } else if (i == n - 1) { CVector3 p; p[0] = 0.5 * width; p[1] = 0.0; p[2] = 1.0; p = M_t * p; x_final = p[0]; y_final = p[1]; } } // Normalize the results mShape = CShape((int)(ceil(max_x) - floor(min_x)), (int)(ceil(max_y) - floor(min_y)), nBands); CByteImage compImage(mShape); NormalizeBlend(accumulator, compImage); bool debug_comp = false; if (debug_comp) WriteFile(compImage, "tmp_comp.tga"); // Allocate the final image shape int outputWidth = 0; if (is360) { outputWidth = mShape.width - width; } else { outputWidth = mShape.width; } CShape cShape(outputWidth, mShape.height, nBands); CByteImage croppedImage(cShape); // Compute the affine transformation CTransform3x3 A = CTransform3x3(); // identify transform to initialize // BEGIN TODO // fill in appropriate entries in A to trim the left edge and // to take out the vertical drift if this is a 360 panorama // (i.e. is360 is true) printf("TODO: %s:%d\n", __FILE__, __LINE__); // END TODO // Warp and crop the composite WarpGlobal(compImage, croppedImage, A, eWarpInterpLinear); return croppedImage; }
int BlendPairs(int argc, const char *argv[]) { // Blend a sequence of images given the pairwise transformations if (argc < 5) { printf("usage: %s pairlist.txt outimg.tga blendWidth\n", argv[1]); return -1; } const char *pairlist= argv[2]; const char *outfile = argv[3]; float blendWidth = (float) atof(argv[4]); // Open the list of image pairs FILE *stream = fopen(pairlist, "r"); if (stream == 0) throw CError("%s: could not open the file %s", argv[1], pairlist); // Construct the list of images and translations CImagePositionV ipList; char line[1024], infile1[1024], infile2[1024]; // float rel_t[2]; CTransform3x3 M; int n; for (n = 0; fgets(line, 1024, stream); n++) { // Compute the position from the PREVIOUS displacement CImagePosition ip; if (n == 0) { ip.position = CTransform3x3::Translation(0.0, 0.0); /* Ident matrix */ // ip.position = CTransform3x3::Rotation(45.0); /* Ident matrix */ } else { ip.position = M * ipList[n-1].position; } // for (int k = 0; k < 2; k++) // ip.position[k] = (n > 0) ? ipList[n-1].position[k] - rel_t[k] : 0.0f; // Read the line and push the image onto the list // if (sscanf(line, "%s %s %f %f", infile1, infile2, // &rel_t[0], &rel_t[1]) != 4) // throw CError("%s: error reading %s", argv[1], pairlist); #if 0 if (sscanf(line, "%s %s %lf %lf", infile1, infile2, &(M[0][2]), &(M[1][2])) != 4) throw CError("%s: error reading %s\n", argv[1], pairlist); #else if (sscanf(line, "%s %s %lf %lf %lf %lf %lf %lf %lf %lf %lf", infile1, infile2, &(M[0][0]), &(M[0][1]), &(M[0][2]), &(M[1][0]), &(M[1][1]), &(M[1][2]), &(M[2][0]), &(M[2][1]), &(M[2][2])) != 11) throw CError("%s: error reading %s\n", argv[1], pairlist); #endif // The coordinate system of the ImageLib images has y reflected -- so let's fix that! // M[1][2] = -M[1][2]; ip.imgName = std::string(infile1); CByteImage imgTmp; ReadFile(imgTmp, infile1); ip.img = CByteImage(imgTmp.Shape()); FlipImage(imgTmp, ip.img); ipList.push_back(ip); } // Read in the last image CImagePosition ip; // for (int k = 0; k < 2; k++) // ip.position[k] = ipList[n-1].position[k] - rel_t[k]; ip.position = M * ipList[n-1].position; ip.imgName = std::string(infile2); CByteImage imgTmp; ReadFile(imgTmp, infile2); ip.img = CByteImage(imgTmp.Shape()); FlipImage(imgTmp, ip.img); ipList.push_back(ip); fclose(stream); CByteImage resultTmp = BlendImages(ipList, blendWidth); // Flip again CByteImage result(resultTmp.Shape()); FlipImage(resultTmp, result); WriteFile(result, outfile); return 0; }