在项目过程中用到了鼠标绘制旋转的操作,这里放出来给大家作为参考。
上面的圆圈用来调整旋转角度,中间的圆圈用来调整位置,后续可添加对大小的修改。
源代码:
#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;
vector 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;
}