3

I'm trying to apply homography transformation on really large images (>30GB). So, my idea is to:

  1. Calculate the homography on the downscaled image.
  2. Do the matrix correction with [1, 1, F, 1, 1, F, 1/F, 1/F, 1] where F is the scaling factor.
  3. Apply "scaled" homography matrix on a full-size image.

Now, the problem with the third step is that I can't put the whole image in the RAM because during the transformation image data is converted from int8 to float, and the image size explodes. So, my question is:

Is there a way to divide the full-size image into separate tiles and then for every tile calculate new homography matrices from the homography calculated in step 2?

Here is the code (I hope it will make some thing clearer):

After calculating homography on downscaled image:

# "Scale" our homograpyhy matrix for the full size image
F = 2**base_lvl # scaling factor
S = [1, 1, F, 1, 1, F, 1/F, 1/F, 1]
S = np.array(S).reshape(3,3)
H_full_size = S * homography
tform = skimage.transform.ProjectiveTransform(matrix=H_full_size)

Here I'm doing transformations on separated channels to save on memory, but ideally I would like to do transformations on tiles:

# create temporary directory for saving single channel transformed arrays
path_tmp = Path('tmp')
path_tmp.mkdir(exist_ok=True)

height, width, channels = z_01[0].shape

zarr_paths = []
for color in range(channels):

    # do the transformation on single color channel
    # this saves RAM
    image = z_02[0][:, :, color]
    warped_img = (skimage.transform.warp(image, tform.inverse, output_shape=(height, width)) * 255.0).astype(np.uint8)

    zarr_paths.append(f'{path_tmp}/array_{color}.zarr')
    zarr.save(zarr_paths[-1], warped_img)

matrix = np.dstack((zarr.load(zarr_paths[0]), zarr.load(zarr_paths[1]), zarr.load(zarr_paths[2])))

Before anyone asks: of course I know how to divide an image into separate tiles. The problem is that, if I understood that correctly, in order to to the transformations on separate tiles, I need to modify homography array, in my case "tform", for every tile. Am I right?

  • How do you want to generate downscale image from original(30GB) one? – BarzanHayati Apr 02 '22 at 13:05
  • My images are in so called "pyramid" representation. I have 8 size levels per image. level 0 is full size, and every next level is half the size of previous level – Krunoslav Vinicki Apr 02 '22 at 14:08
  • your 1-F-"matrix" looks wrong, *very wrong*. please check. -- matrices can be multiplied (matrix mul.) and like that you can fold a scaling matrix, *or a translation matrix*, into the homography. the matrix you gave is __not__ a scaling matrix and __not__ a translation matrix. it's something absolutely unreasonable. it has coefficients in the division/projection row. – Christoph Rackwitz Apr 02 '22 at 15:07
  • your **real** question is how to _not_ load an entire picture file, but just parts of it... and that requires library support **and** format support (the format has to make it possible) – Christoph Rackwitz Apr 02 '22 at 15:09
  • do you have code or an example of where you are up to so far ? – D.L Apr 02 '22 at 15:11
  • I added the code – Krunoslav Vinicki Apr 02 '22 at 15:51

0 Answers0