Ask Your Question

Revision history [back]

you can use minAreaRect() function that returns a RotatedRect having angle

you can use minAreaRect() function that returns a RotatedRect having angle

you can test 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;
}

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;
}