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

来源:互联网 发布:网络信息安全的概念 编辑:程序博客网 时间:2024/05/02 02:03

在项目过程中用到了鼠标绘制旋转的操作,这里放出来给大家作为参考。
上面的圆圈用来调整旋转角度,中间的圆圈用来调整位置,后续可添加对大小的修改。
这里写图片描述
源代码:

#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <math.h>#include <iostream>using namespace cv;using namespace std;#define DRAWMODE   1#define SHOWMODE   0bool DrawRectMode = false, AdjustAngleMode = false, AdjustPositionMode = false;Rect temStorage;vector<Rect> RectContainer;vector<pair<RotatedRect, Point>> AdjustedRectContainer;vector<pair<RotatedRect, RotatedRect>>    distanceTools;int adjustAngleID = 0, adjustPositionID = 0;const string winName = "showWindow";bool serchRotatedPoint(vector<pair<RotatedRect, Point>> 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<pair<RotatedRect, Point>> 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<pair<RotatedRect, Point>> 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;    vector<RotatedRect>PerspectivedRectContainer;    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;}
1 0