you can use minAreaRect() function that returns a RotatedRect having angle
you can test the code below
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src, gray;
src = imread("e:/test/rr.jpg");
if (src.empty())
return -1;
cvtColor(src, gray, COLOR_BGR2GRAY);
gray = gray > 100;
imshow("gray", gray);
vector<vector<Point> > contours;
findContours(gray.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
RotatedRect _minAreaRect;
for (size_t i = 0; i < contours.size(); ++i)
{
_minAreaRect = minAreaRect(contours[i]);
Point2f pts[4];
_minAreaRect.points(pts);
cout << "minAreaRect.angle: " << _minAreaRect.angle << endl;
for (int j = 0; j < 4; j++)
line(src, pts[j], pts[(j + 1) % 4], Scalar(0, 0, 255), 1, LINE_AA);
}
imshow("result", src);
waitKey(0);
return 0;
}
also see the code below (adopted from the code on stackoverflow)
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
//! Compute the distance between two points
/*! Compute the Euclidean distance between two points
*
* @Param a Point a
* @Param b Point b
*/
static double distanceBtwPoints(const cv::Point2f &a, const cv::Point2f &b)
{
double xDiff = a.x - b.x;
double yDiff = a.y - b.y;
return std::sqrt((xDiff * xDiff) + (yDiff * yDiff));
}
int main(int argc, char** argv)
{
Mat src, gray;
src = imread(argv[1]);
if (src.empty())
return -1;
cvtColor(src, gray, COLOR_BGR2GRAY);
gray = gray > 100;
imshow("gray", gray);
vector<vector<Point> > contours;
findContours(gray.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
RotatedRect _minAreaRect;
for (size_t i = 0; i < contours.size(); ++i)
{
_minAreaRect = minAreaRect(contours[i]);
Point2f pts[4];
_minAreaRect.points(pts);
double dist0 = distanceBtwPoints(pts[0], pts[1]);
double dist1 = distanceBtwPoints(pts[1], pts[2]);
double angle = 0;
// if (dist0 > dist1 * 4)
angle = atan2(pts[0].y - pts[1].y, pts[0].x - pts[1].x) * 180.0 / CV_PI;
// if (dist1 > dist0 * 4)
// angle = atan2(pts[1].y - pts[2].y, pts[1].x - pts[2].x) * 180.0 / CV_PI;
cout << "minAreaRect.angle: " << _minAreaRect.angle << endl;
cout << "angle: " << angle;
for (int j = 0; j < 4; j++)
line(src, pts[j], pts[(j + 1) % 4], Scalar(0, 0, 255), 1, LINE_AA);
}
imshow("result", src);
waitKey(0);
return 0;
}