【OpenCV】通过鼠标在图像中绘制RotatedRect旋转矩形

在项目过程中用到了鼠标绘制旋转的操作,这里放出来给大家作为参考。
上面的圆圈用来调整旋转角度,中间的圆圈用来调整位置,后续可添加对大小的修改。
【OpenCV】通过鼠标在图像中绘制RotatedRect旋转矩形_第1张图片
源代码:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"


#include 
#include 

using namespace cv;
using namespace std;
#define DRAWMODE   1
#define SHOWMODE   0
bool DrawRectMode = false, AdjustAngleMode = false, AdjustPositionMode = false;
Rect temStorage;
vector RectContainer;
vector> AdjustedRectContainer;
vector>    distanceTools;
int adjustAngleID = 0, adjustPositionID = 0;

const string winName = "showWindow";


bool serchRotatedPoint(vector> AdjustedRectContainer, int x, int y, int radius, int &idx)
{
    int size = AdjustedRectContainer.size();
    if (size <= 0)
        return false;
    for (int i = 0; i < size; i++)
    {
        if (abs(x - AdjustedRectContainer[i].second.x) < radius &&
            abs(y - AdjustedRectContainer[i].second.y) < radius)
        {
            idx = i;
            return true;
        }
    }
    return false;
}
bool serchCenterPoint(vector> AdjustedRectContainer, int x, int y, int radius, int &idx)
{
    int size = AdjustedRectContainer.size();
    if (size <= 0)
        return false;
    for (int i = 0; i < size; i++)
    {
        if (abs(x - AdjustedRectContainer[i].first.center.x) < radius &&
            abs(y - AdjustedRectContainer[i].first.center.y) < radius)
        {
            idx = i;
            return true;
        }
    }
    return false;
}
void DrawRotatedRects(Mat &img, vector> AdjustedRectContainer, int Mode=1)
{
    for (int i = 0; i < AdjustedRectContainer.size(); i++)
    {
        Point2f vertices[4];
        AdjustedRectContainer[i].first.points(vertices);
        Point2f rotatedPoint = AdjustedRectContainer[i].second;
        Point2f center = AdjustedRectContainer[i].first.center;
        for (int j = 0; j < 4; j++)
        {
            line(img, vertices[j % 4], vertices[(j + 1) % 4], Scalar(0, 255, 0), 1);
        }
        if (Mode == DRAWMODE)
        {
            circle(img, rotatedPoint, 3, Scalar(0, 255, 0), 2);
            circle(img, center, 3, Scalar(0, 255, 0), 2);
        }

    }
}
void onMouse(int event, int x, int y, int, void*)
{
    if (DrawRectMode)
    {
        temStorage.width = x - temStorage.x;
        temStorage.height = y - temStorage.y;
    }
    else if (AdjustAngleMode)
    {
        float angle = atan((AdjustedRectContainer[adjustAngleID].first.center.y - y)
            / (AdjustedRectContainer[adjustAngleID].first.center.x - x));
        AdjustedRectContainer[adjustAngleID].first.angle = angle * 180 / CV_PI;
        AdjustedRectContainer[adjustAngleID].second = Point2f(x, y);
    }
    else if (AdjustPositionMode)
    {
        AdjustedRectContainer[adjustPositionID].first.center = Point(x, y);
    }
    if (event == CV_EVENT_LBUTTONDOWN)
    {
        if (serchRotatedPoint(AdjustedRectContainer, x, y, 5, adjustAngleID))
        {
            AdjustAngleMode = true;
        }
        else if (serchCenterPoint(AdjustedRectContainer, x, y, 5, adjustPositionID))
        {
            AdjustPositionMode = true;
        }
        else{
            DrawRectMode = true;//鼠标按下的标志赋真值
            temStorage.x = x;
            temStorage.y = y;
            temStorage.width = 0;
            temStorage.height = 0;
        }

    }
    else if (event == CV_EVENT_LBUTTONUP)
    {
        DrawRectMode = false;
        if (AdjustAngleMode)
        {
            AdjustAngleMode = false;
            Point2f vertices[4];
            AdjustedRectContainer[adjustAngleID].first.points(vertices);
            AdjustedRectContainer[adjustAngleID].second = vertices[2];
        }
        else if (AdjustPositionMode)
        {
            AdjustPositionMode = false;
            Point2f vertices[4];
            AdjustedRectContainer[adjustPositionID].first.points(vertices);
            AdjustedRectContainer[adjustPositionID].second = vertices[2];
        }
        else if (temStorage.area()>60)
        {
            RectContainer.push_back(temStorage);
        }
    }
}
int main(int argc, char** argv)
{
    //double t = (double)getTickCount();

    namedWindow("drawWindow");
    setMouseCallback("drawWindow", onMouse, 0);

    Mat img1 = imread("1367111070500.jpg");
    Mat img2 = imread("1367111070500.jpg");
    Mat showImg1,showImg2;


    if (img1.empty())
    {
        cout << "Can not read images" << endl;
        return -1;
    }

    namedWindow(winName, 1);
    //t = ((double)getTickCount() - t) / getTickFrequency();
    //cout << "running time : " << t << " s" << endl;
    char c = ' ';
    bool ModeFlag = true;
    vectorPerspectivedRectContainer;
    while (c != 'm')
    {
        resize(img1, showImg1, Size(img1.cols / 1.0, img1.rows / 1.0));
        resize(img2, showImg2, Size(img1.cols / 1.0, img1.rows / 1.0));
        if (c == 'a')
            ModeFlag = false;
        if (ModeFlag)
        {
            AdjustedRectContainer.clear();
            for (int i = 0; i < RectContainer.size(); i++)
            {
                rectangle(showImg1, RectContainer[i], Scalar(0, 255, 0), 1);
                Point2f center = Point2f(RectContainer[i].x + RectContainer[i].width / 2.0, RectContainer[i].y + RectContainer[i].height / 2.0);
                RotatedRect rotatedRect = RotatedRect(center, Size(RectContainer[i].width, RectContainer[i].height), 0.0);
                Point2f rotatedPoint = Point2f(RectContainer[i].x + RectContainer[i].width / 2.0, RectContainer[i].y);
                AdjustedRectContainer.push_back(make_pair(rotatedRect, rotatedPoint));
                circle(showImg1, rotatedPoint, 3, Scalar(0, 255, 0), 2);
                circle(showImg1, center, 3, Scalar(0, 255, 0), 2);
            }
            rectangle(showImg1, temStorage, Scalar(0, 255, 0), 2);
        }
        else{
            PerspectivedRectContainer.clear();
            DrawRotatedRects(showImg1, AdjustedRectContainer, DRAWMODE);
            //在待检图像中绘制检测矩形
            DrawRotatedRects(showImg2, AdjustedRectContainer, SHOWMODE);
        }
        imshow(winName, showImg2);
        imshow("drawWindow", showImg1);
        c = waitKey(1);
    }
    return 0;
}

你可能感兴趣的:(OpenCV)