From: Graham on
Hi there,

Say I rotate an image, I, by x degrees and want to add to the same image rotated by y degrees (using imrotate). The corners of the images must not be cropped off, obviously. How do I add the two images without getting, '??? Error using ==> plus, Matrix dimensions must agree.'

I know it must have something to do with padding with zeros so that the rotated images have the same size, but I can't figure out how to do it.

Thanks


From: Walter Roberson on
Graham wrote:

> Say I rotate an image, I, by x degrees and want to add to the same image
> rotated by y degrees (using imrotate). The corners of the images must
> not be cropped off, obviously. How do I add the two images without
> getting, '??? Error using ==> plus, Matrix dimensions must agree.'
>
> I know it must have something to do with padding with zeros so that the
> rotated images have the same size, but I can't figure out how to do it.

Choose a centre of rotation. There will be a point in the image (or a
set of points in the image) that are furthest from the centre of
rotation. The projection on to the x and y axes of those furthest points
as the image rotates is going to dictate the size of the rectangular
matrix you would need to store the rotated image [though I would need to
think more about the appropriate point to pick for the rotation of the
"near" edge if the centre of rotation is significantly different from
the centre of the image.) Once you know the pounds that are going to
provide your constraints, it is a fairly simple 2 x 2 matrix
multiplication to determine the location of the constraining points
after the rotation by the known angles. The task is logically simplified
if you are rotating around the centre of a rectangualr image, in that
you do not need to exert any work to locate the extrema: the extrema
would be the diagonal corners of the image.


If I recall correctly, imrotate automatically expands the matrix and
fills the previously-unused portions with whatever fill value you wish.
If my memory is correct, just do the two imrotates separately. After
that, it is just a matter of using size() to determine which image is
larger, and of padding the smaller image with outside rows or columns of
the fill value. It could even be the case that you will need to pad one
of the images in one direction and to pad the other image in the other
direction so as to arrive at a common size.

Just make sure that however you do the filling, that the locations that
were the centre of rotation end up in the correct positions relative to
each other. For example if you had an image whose height was an odd
number and whose width was an even number, and you rotate it 90 degrees
while the second image is "rotated by 0 degrees", then the most natural
thing to want to do would be to pad by an odd number in one direction
and an even number in the other direction so as to arrive at the common
size -- but if you do that, then the centre of the image could end up
shifting in one of the images due to the asymmetrical padding. This
could be a non-trivial issue: the centre of an odd pixel count is the
centre of the middle pixel, but the centre of an even pixel count is the
boundary between the two halves, so after rotation by 90 degrees,
naive processing would be expecting the center at (boundary, middle) to
match up with a center at (middle, boundary). I'll let you work out how
to deal with this. (Read: I need some lunch before I can think through
this clearly.)