How to rotate relative points in degrees?

1k Views Asked by At

I have 4 points in range [0.0, 1.0] representing the top-left and bottom-right corners of a bounding box.

For example: [0.25 0.33 0.71 0.73]

In other words, the first pair (in (y, x) format) means that the point is 25% down the top of the image, and 33% from the left. The second pair means that the bottom right point is located 71% from the top of the image and 73% from the left.

Question

If I now rotate the image by N degrees, how do I compute where those 4 points should be? To be more specific, I really only care to rotate the image 90, 180, 270 degrees.

enter image description here

Left: original image, not rotated. Right: image rotated 90 degrees.

2

There are 2 best solutions below

0
On BEST ANSWER

The transformation you require is: $$ y’ = y \cos \theta + x \sin \theta $$ $$x’ = -y \sin \theta+ x \cos \theta$$

Also don’t forget that when programming $\ cos \theta$ and $ \sin \theta$ needs to be in radians and not degrees. To convert from degrees to radians multiply by $\pi/180$.

You will note that the above formula is greatly simplified if the rotation angles are multiples of $90 \deg$.

For 0 degrees, $y’ = y, \; x’ = x $

For 90 degrees, $ y’ = x, \; x’ = -y $

For 180 degrees,$ y’ = -y, \;x’ = - x $

For 270 degrees, $y’ = -x, \;x’ = y $

If the final coordinates all have to be positive, as is the case for many image processing contexts, this should be modified to

For 0 degrees, $y’ = y, \; x’ = x $

For 90 degrees, $ y’ = x, \;x’ =1 -y $

For 180 degrees,$ y’ = 1-y, \;x’ =1 - x $

For 270 degrees, $y’ =1 -x, \; x’ = y$

Finally, I note that the order of $x$ and $y$ coordinates that you use (although used in image processing fairly often) are reversed to the standard math convention so be careful if you are searching for other solutions on the internet that you are reading the correctly!

Hope that helps!

0
On

Based off Martin Roberts answer, here's my complete solution:

  // values in absolute pixels
  box = [y_min, x_min, y_max, x_max];

  // Make points relative to image
  pct = [box[0] / height, box[1] / width, box[2] / height, box[3] / width];
  //^
  //|
  //+--------+
  //         |
  //         v
  rot90 = [pct[1], 1 - pct[2], pct[3], 1 - pct[0]];
  // ^
  // |
  // +--------+
  //          |
  //          v
  rot180 = [rot90[1], 1 - rot90[2], rot90[3], 1 - rot90[0]];
  // ^
  // |
  // +--------+
  //          |
  //          v

  rot270 = [rot180[1], 1 - rot180[2], rot180[3], 1 - rot180[0]];

enter image description here

  • As a minor implementation detail, although not all images in my dataset were squares, they were deliberately reshaped to be squares because of the neural network model where they'll be used.
  • The reason for the reversed (x, y) points, that's because TensorFlow's tf.image.draw_bounding_boxes expects the points in that order.