Search code examples
imagematlabimage-registration

Crop borders after image transformation using MATLAB


How can I automatically crop the black borders after transforming (rotation, translation, scale and shear) an image?

I am using an intensity-based automatic image registration (imregtform, optimizer, imregister....) to rotate one image to fit the other. Now after rotation, I need to crop both images to have the same size, and still be lined up.

The simplest representation of what the rotated image will look like would be a white square to which the transformation matrix was applied.

An example of what a set of the actual images I am using would look like can be seen here.

I assume the fact, that the image may have zero-value pixels at its edges may complicate the operation, although I assume the whole images will be non-zero, due to noise.

Maybe I can use the transformation matrix to actually calculate the border that needs cropping. in the example above the matrix was:

 0,999428374496743      0,00888472048904662   0
-0,00888472048904659    0,999428374496743     0
 3,79626401832983      -0,493066986575474     1

The matrix is listed in a '1x1 affine 2d' object in the workspace. I wasn't able to find out the syntax to use it from there.


Solution

  • I have figured out a way of doing it, although it is not very elegant, hence I'd still be interested in a nice way of solving this.

    One can apply the transformation matrix to the four corner points of the image, and use these new points as the cropping limits. One should make sure that the cropping corners are within the original image or need to be fixed to the edges.

    % width and length of the input image
    width = size(img_fixed,1);
    height = size(img_fixed,2);
    
    % transform the four corners of the image to find crop area
    [x1,y1] = transformPointsForward(T,0,0);
    [x2,y2] = transformPointsForward(T,width,0);
    [x3,y3] = transformPointsForward(T,width,height);
    [x4,y4] = transformPointsForward(T,0,height);
    
    % find inner most borders for a rectangular crop
    if max([x1,x4]) < 0
        x_left = 0;      
    else
        x_left = ceil(max([x1,x4]));
    end
    
    if min([x2,x3]) > width
        x_right = width;     
    else
        x_right = floor(min([x2,x3]));
    end
    
    if max([y1,y2]) < 0
        y_top = 0;   
    else
        y_top = ceil(max([y1,y2])); 
    end
    
    if min([y3,y4]) > height
        y_bottom = height;      
    else
        y_bottom = floor(min([y3,y4]));
    end
    
    img_fixed_crop = imcrop(img_fixed,[x_left y_top x_right-x_left y_bottom-y_top]);
    img_moving_crop = imcrop(img_moving,[x_left y_top x_right-x_left y_bottom-y_top]);