Now that we have eliminated scaling from our rotation images, we can now try to track/follow our region of interest (ROI) throughout all rotations. Below is the first initial attempt, we marked our first ROI so we know the left most point of the rectangle as well as its dimensions (width and height). So we then derived the new left most point of the shifted rectangle.
The GREEN box is the one that I initially marked, and the BLUE boxes are the ones that are derived from the original marked ROI and the shift in angle rotation. So it is supposed to track the ROI through all rotations. As you can see this is not handled quite right. The upper left hand corner of the box which is always the starting point of cvRect structure, does in fact follow the shift position at each rotation but the actual area of the rectangle is wrong. For example when we get to about degree rotation 90, the box should be inverted, as to cover the area but it still assumes a top down orientation from our rotation point.

In order to overcome this problem a rotation on the derived rectangle would be necessary. OpenCV does not draw rectangles at a rotation, so instead of needing just one point, width and height to describe an upright rectangle, we need to know all the points in the rotated rectangle.

//Get the distance from the center to our point of interest
int a = x - src_center.x;
int b = y - src_center.y;
double distance = sqrt((double)((a*a) + (b*b)));

//Convert the angle to radians
double radians = angle * (PI/180);

//Get the deltas (changes) in our x and y coordinate from our formula above
float deltaX = cos(radians) * a + sin(radians) * b;
float deltaY = cos(radians) * b - sin(radians) * a;

//Add the delta (change) values to our initial point value to get the shift and new coordinates
float newXPos = src_center.x + deltaX;
float newYPos = src_center.y + deltaY;

//Get the rotated rectangle values, from our ROI rotated at a angle value
cv::RotatedRect rect = RotatedRect(cvPoint((newXPos + (widthOfROI/2)), (newYPos + (heightOfROI/2))), Size2f(widthOfROI, heightOfROI), abs(angle));

//Create a holder for 4 points of our rotated rectangle.
CvPoint2D32f box_vtx[4];
cvBoxPoints(rect, box_vtx);

Once you have your 4 points in your rotated rectangle all you then need to do is loop through each point and draw a line connecting each one together, which results in a box drawn on your image. In the below video clip the GREEN box is our initial marked ROI, the BLUE box is our initial tracking implementation that assumed a top down orientation from the top left most corner point that we referenced and the YELLOW box is the new implementation that includes rotating the derived ROI (BLUE box) based on the anchored point in the upper left most corner, which you will notice the BLUE and YELLOW are always anchored at the same point in all rotations.

Tags: , , ,

Leave a Reply