void Align::align(void) { std::cout << "Registering input images..." << std::endl; // Vector containing the shift values in x and y between images i and i+1 std::vector<std::vector<int>> consecutiveShifts(images->size()-1, std::vector<int>(2,0)); // Compute the offsets between one image and the next one in the list for (unsigned int i=0; i<images->size()-1; i++) { // Calculate the consecutive shifts in x and y between the current image and the next one std::cout << "Calculating shift between image " << i << " and image " << i+1 << "..." << std::endl; getExpShift((*images)[i], (*images)[i+1], shift_bits, consecutiveShifts[i]); #ifdef DEBUG std::cout << "Shift between image " << i << " and image " << i+1 << ":\n" << "\tx: " << consecutiveShifts[i][0] << "\n" << "\ty: " << consecutiveShifts[i][1] << std::endl; #endif } // end for all image pairs // Build a matrix of offsets from any image to any other one. updateRelativeShifts(consecutiveShifts); // Use this matrix to crop the images so that they // have the same size and are correctly registered cropImages(); };
void getExpShift(const Array2D8u& img1, const int median1, const Array2D8u& img2, const int median2, const int noise, const int shift_bits, int &shift_x, int &shift_y) { assert(img1.getCols() == img2.getCols()); assert(img1.getRows() == img2.getRows()); int curr_x = 0; int curr_y = 0; if (shift_bits > 0) { Array2D8u img1small(img1.getCols()/2, img1.getRows()/2); Array2D8u img2small(img2.getCols()/2, img2.getRows()/2); pfs::resize(img1, img1small); pfs::resize(img2, img2small); getExpShift(img1small, median1, img2small, median2, noise, shift_bits-1, curr_x, curr_y); curr_x *= 2; curr_y *= 2; } Array2Db img1threshold(img1.getCols(), img1.getRows()); Array2Db img1mask(img1.getCols(), img1.getRows()); Array2Db img2threshold(img2.getCols(), img2.getRows()); Array2Db img2mask(img2.getCols(), img2.getRows()); setThreshold(img1, median1, noise, img1threshold, img1mask); setThreshold(img2, median2, noise, img2threshold, img2mask); Array2Db img2_shifted(img2.getCols(), img2.getRows()); Array2Db img2mask_shifted(img2.getCols(), img2.getRows()); int minerr = img1.size(); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int dx = curr_x + i; int dy = curr_y + j; pfs::shift(img2threshold, dx, dy, img2_shifted); pfs::shift(img2mask, dx, dy, img2mask_shifted); long err = XORimages(img1threshold, img1mask, img2_shifted, img2mask_shifted); if ( err < minerr ) { minerr = err; shift_x = dx; shift_y = dy; } } } PRINT_DEBUG("getExpShift::Level " << shift_bits << " shift (" << shift_x << "," << shift_y << ")"); }
void Align::getExpShift(const Image& img1, const Image& img2, int shift_bits, std::vector<int>& shift_ret) { std::vector<int> cur_shift(2, 0); int i, j; if (shift_bits > 0) { Image sml_img1 = img1.shrink2(); Image sml_img2 = img2.shrink2(); getExpShift(sml_img1, sml_img2, shift_bits-1, cur_shift); cur_shift[0] *= 2; cur_shift[1] *= 2; } else { cur_shift[0] = cur_shift[1] = 0; } Bitmap tb1; img1.computeThresholdBitmap(tb1); Bitmap eb1; img1.computeExclusionBitmap(eb1); Bitmap tb2; img2.computeThresholdBitmap(tb2); Bitmap eb2; img2.computeExclusionBitmap(eb2); int min_err = img1.rows * img1.cols; for (i=-1; i<=1; i++) { for (j=-1; j<=1; j++) { if (min_err > 0) { int xs = cur_shift[0] + i; int ys = cur_shift[1] + j; Bitmap shifted_tb2(img1.rows, img1.cols); Bitmap shifted_eb2(img1.rows, img1.cols); Bitmap diff_b(img1.rows, img1.cols); bitmapShift(tb2, xs, ys, shifted_tb2); bitmapShift(eb2, xs, ys, shifted_eb2); bitmapXOR(tb1, shifted_tb2, diff_b); bitmapAND(diff_b, eb1, diff_b); bitmapAND(diff_b, shifted_eb2, diff_b); int err = diff_b.total(); if (err < min_err) { shift_ret[0] = xs; shift_ret[1] = ys; min_err = err; } } } // end for j } // end for i };
void mtbalign(const pfs::Frame& image1, const pfs::Frame& image2, const double quantile, const int noise, const int shift_bits, int &shift_x, int &shift_y) { Array2D8u img1lum; Array2D8u img2lum; int median1 = getLum(image1, img1lum, quantile); int median2 = getLum(image2, img2lum, quantile); PRINT_DEBUG("align::medians, image 1: " << median1 << ", image 2: " << median2); getExpShift(img1lum, median1, img2lum, median2, noise, shift_bits, shift_x, shift_y); PRINT_DEBUG("align::done, final shift is (" << shift_x << "," << shift_y <<")"); }