Skip to content

[POC] : subdivision by bloc size  #601

@adebardo

Description

@adebardo

Context

The CNES QI team is interested in the possibility of performing block-based coregistration, which is why studies are currently being conducted to test this functionality, referred to as blockwise. At the moment, users must specify the number of subdivisions they wish to apply. However, the QI team would prefer to specify block sizes instead. The goal of this ticket is to propose an implementation of this capability.

We will start the process of managing the size of an overlap between tiles. In this ticket, it will have a default value, and another ticket will be opened later to better manage this overlap.

Proposed Code

Currently, subdivision is handled by the subdivide_array function, so we propose managing block sizes at this level.

  1. Extend Subdivision:
    Currently, users input a number, but instead, we could allow them to input a dictionary or list containing two integers for rows and columns, and then calculate the number of subdivisions based on these values.
    For example, for an image of size 985x1332:

    • Scenario 1: Subdivision 64, 8 rows/8 columns, block size of 123 rows by 166 columns.
    • Scenario 2: Block size of 100x100, 10 row blocks, 14 column blocks, 10*14 = 140 blocks.
  2. Update the Following:

    def subdivide_array(self, shape: tuple[int, ...]) -> NDArrayf:  
        """  
        Return the grid subdivision for a given DEM shape.  
        :param shape: The shape of the input DEM.  
        :returns: An array of shape 'shape' with 'self.subdivision' unique indices.  
        """  
        if len(shape) == 3 and shape[0] == 1:  # Account for (1, row, col) shapes  
            shape = (shape[1], shape[2])  
    
        if isinstance(self.subdivision, list):  
            nb_bloc_row = np.ceil(shape[0] / self.subdivision[0])  
            nb_bloc_col = np.ceil(shape[1] / self.subdivision[1])  
    
            self.subdivision = int(nb_bloc_row * nb_bloc_col)  
    
        return subdivide_array(shape, count=self.subdivision)
    • Update the associated docstring.

    • Copy a function that allow blocks to overlap

def patchify(arr, nblocks, overlap):
           # manually split with overlap a datacube for parallel computing
       
           overlap = int(np.floor(overlap))
           patches = []
           nx, ny = np.shape(arr)
       
           nx_sub = nx // nblocks[0]
           ny_sub = ny // nblocks[1]
       
           split = [[nx_sub * i, min(nx_sub * (i + 1), nx), ny_sub * j, min(ny_sub * (j + 1), ny)] for i in
                    range(nblocks[0] + 1) for j in range(nblocks[1] + 1)]
           over = [[max(0, l[0] - overlap), min(nx, l[1] + overlap), max(0, l[2] - overlap), min(l[3] + overlap, ny)] for l in
                   split]
           inv = []
           for k in range(len(split)):
               x0, x1, y0, y1 = split[k]
               i0, i1, j0, j1 = over[k]
               patches.append(arr[i0:i1, j0:j1])
               inv.append([x0 - i0, x1 - i0, y0 - j0, y1 - j0])

   return patches, inv, split
  • Replace the groups variable here by calling function patchify

Tests

  • A test should be added to this test with a parameter containing a list (or a dict) of tile sizes for rows and columns.
  • Unit tests should be implemented for patchify function

Documentation

  • It would be helpful to add a comment in the plot_blockwise_coreg file to inform users that an alternative solution is available.

/ estimate 5d

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions