So you can do this with the minAreaRect openCV function. It is written in C ++, but you can probably adapt it easily, since almost all OpenCV functions were used.
cv::Mat input = cv::imread("../inputData/rectangles.png"); cv::Mat gray; cv::cvtColor(input,gray,CV_BGR2GRAY); // since your image has compression artifacts, we have to threshold the image int threshold = 200; cv::Mat mask = gray > threshold; cv::imshow("mask", mask); // extract contours std::vector<std::vector<cv::Point> > contours; cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); for(int i=0; i<contours.size(); ++i) { // fit bounding rectangle around contour cv::RotatedRect rotatedRect = cv::minAreaRect(contours[i]); // read points and angle cv::Point2f rect_points[4]; rotatedRect.points( rect_points ); float angle = rotatedRect.angle; // angle // read center of rotated rect cv::Point2f center = rotatedRect.center; // center // draw rotated rect for(unsigned int j=0; j<4; ++j) cv::line(input, rect_points[j], rect_points[(j+1)%4], cv::Scalar(0,255,0)); // draw center and print text std::stringstream ss; ss << angle; // convert float to string cv::circle(input, center, 5, cv::Scalar(0,255,0)); // draw center cv::putText(input, ss.str(), center + cv::Point2f(-25,25), cv::FONT_HERSHEY_COMPLEX_SMALL, 1, cv::Scalar(255,0,255)); // print angle }
which leads to this image:

as you can see, the corners are probably not what you want (because they randomly use a longer or smaller line as a reference). Instead, you can extract the longer sides of the rectangles and calculate the angle manually.
If you select the longer edge of the rotating rectangles and calculate the angle from it, it will look like this:
giving this result, which should be what you are looking for!

EDIT: It looks like op is not using the input image that it placed, since the supporting rectangular centers lie outside the image.
Using this input (manually scaled, but probably still not optimal):

I get these results (blue dots are the centers of the support rectangles provided by the operator):

Comparison of link with detection:
reference (x,y,angle) detection (x,y,angle) (320,240,0) (320, 240, 180) // angle 180 is equal to angle 0 for lines (75,175,90) (73.5, 174.5, 90) (279,401,170) (279.002, 401.824, 169.992) (507,379,61) (507.842, 379.75, 61.1443) (545,95,135) (545.75, 94.25, 135) (307,79,37) (306.756, 77.8384, 37.1042)
I would really like to see the REAL input image, perhaps the result will be even better.