-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPolygonPattern.cpp
More file actions
200 lines (162 loc) · 5.28 KB
/
PolygonPattern.cpp
File metadata and controls
200 lines (162 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "PolygonPattern.h"
cv::Mat PolygonPattern::polyCanvas = cv::Mat();
PolygonPattern::PolygonPattern()
{
m_area = -1.0;
m_flipState = false;
}
void PolygonPattern::setFlipState(bool flipState)
{
m_flipState = flipState;
if(m_flipState == true && m_cntPt2fs_flip.empty())
{
//计算翻转后的轮廓点
m_cntPt2fs_flip.resize(m_cntPt2fs.size());
for(int i=0;i<m_cntPt2fs.size();i++)
{
float newX = polyCanvas.cols - m_cntPt2fs[i].x;
float newY = m_cntPt2fs[i].y;
m_cntPt2fs_flip[m_cntPt2fs.size()-1-i] = cv::Point2f(newX,newY);
}
}
}
bool PolygonPattern::getFlipState()
{
return m_flipState;
}
void PolygonPattern::setPoints(const std::vector<cv::Point> &cntPts)
{
//转为Point2f,赋给m_cntPt2fs
pointToPoint2f(cntPts,m_cntPt2fs);
//给m_angles分配存储空间并初始化
m_angles.resize(m_cntPt2fs.size());
for(int i=0;i<m_angles.size();i++)
m_angles[i] = -1.0;
//给m_angles_flip分配存储空间并初始化
m_angles_flip.resize(m_cntPt2fs.size());
for(int i=0;i<m_angles_flip.size();i++)
m_angles_flip[i] = -1.0;
}
void PolygonPattern::setPoint2fs(const std::vector<cv::Point2f> &cntPts)
{
//赋给m_cntPt2fs
m_cntPt2fs.assign(cntPts.begin(),cntPts.end());
//给m_angles分配存储空间并初始化
m_angles.resize(m_cntPt2fs.size());
for(int i=0;i<m_angles.size();i++)
m_angles[i] = -1.0;
//给m_angles_flip分配存储空间并初始化
m_angles_flip.resize(m_cntPt2fs.size());
for(int i=0;i<m_angles_flip.size();i++)
m_angles_flip[i] = -1.0;
}
cv::Point2f PolygonPattern::getCntPoint(int pointId) const
{
if(m_flipState == false)
return m_cntPt2fs[pointId];
else
return m_cntPt2fs_flip[pointId];
}
void PolygonPattern::getAllCntPoint2fs(std::vector<cv::Point2f> &cntPts) const
{
if(m_flipState == false)
cntPts.assign(m_cntPt2fs.begin(),m_cntPt2fs.end());
else
cntPts.assign(m_cntPt2fs_flip.begin(),m_cntPt2fs_flip.end());
}
void PolygonPattern::getAllCntPoints(std::vector<cv::Point> &cntPts)
{
if(m_flipState == false)
{
//确保只计算一次
if(m_cntPts.empty())
point2fToPoint(m_cntPt2fs,m_cntPts);
cntPts.assign(m_cntPts.begin(),m_cntPts.end());
}
else
{
//确保只计算一次
if(m_cntPts_flip.empty())
point2fToPoint(m_cntPt2fs_flip,m_cntPts_flip);
cntPts.assign(m_cntPts_flip.begin(),m_cntPts_flip.end());
}
}
int PolygonPattern::getPrevCntPointId(int currentPointId) const
{
return getPrevIndex(m_cntPt2fs.size(),currentPointId);
}
int PolygonPattern::getNextCntPointId(int currentPointId) const
{
return getNextIndex(m_cntPt2fs.size(),currentPointId);
}
int PolygonPattern::getCntPtsSize() const
{
return m_cntPt2fs.size();
}
float PolygonPattern::getAngle(int pointId)
{
if(m_flipState == false)
{
//确保只计算一次
if(m_angles[pointId] == -1.0)
{
//找到该角的三个点
cv::Point2f pt1 = m_cntPt2fs[getPrevCntPointId(pointId)];
cv::Point2f pt2 = m_cntPt2fs[pointId];
cv::Point2f pt3 = m_cntPt2fs[getNextCntPointId(pointId)];
//计算角度
float angle = calcAngle(pt1,pt2,pt3);
//根据凹凸性更正角度
//if(!isConvexCorner(pt1,pt2,pt3))
// angle = 2*CV_PI - angle;
if(m_cntPts.empty())
point2fToPoint(m_cntPt2fs,m_cntPts);
if(!isConvexCorner2(m_cntPts,pointId))
angle = 2*CV_PI - angle;
m_angles[pointId] = angle;
}
return m_angles[pointId];
}
else
{
//确保只计算一次
if(m_angles_flip.empty())
m_angles_flip.resize(m_cntPt2fs.size());
if(m_angles_flip[pointId] == -1.0)
{
//找到该角的三个点
cv::Point2f pt1 = m_cntPt2fs_flip[getPrevCntPointId(pointId)];
cv::Point2f pt2 = m_cntPt2fs_flip[pointId];
cv::Point2f pt3 = m_cntPt2fs_flip[getNextCntPointId(pointId)];
//计算角度
float angle = calcAngle(pt1,pt2,pt3);
//根据凹凸性更正角度
if(!isConvexCorner(pt1,pt2,pt3))
angle = 2*CV_PI - angle;
m_angles_flip[pointId] = angle;
}
return m_angles_flip[pointId];
}
}
void PolygonPattern::setCanvasSize(int sideLength)
{
polyCanvas = cv::Mat(sideLength,sideLength,CV_8U,cv::Scalar(0));
}
float PolygonPattern::getArea()
{
//确保只计算一次
if(m_area == -1.0)
{
polyCanvas = cv::Scalar(0);
std::vector<std::vector<cv::Point>> contours(1);
point2fToPoint(m_cntPt2fs,contours[0]);
cv::drawContours(polyCanvas,contours,0,255,-1);
m_area = cv::countNonZero(polyCanvas);
/*
if(m_cntPts.empty())
point2fToPoint(m_cntPt2fs,m_cntPts);
m_area = scanArea(m_cntPts,0,polyCanvas.cols,0,polyCanvas.rows);
*/
}
return m_area;
}