-
Notifications
You must be signed in to change notification settings - Fork 0
/
ltROI.h
209 lines (154 loc) · 5.55 KB
/
ltROI.h
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
201
202
203
204
205
206
207
208
209
#ifndef LTROI_H
#define LTROI_H
//#include <cv.h> //Deprecated Header
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cereal/archives/json.hpp>
#include <cereal/archives/xml.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/types/tuple.hpp>
#include <cereal/types/memory.hpp>
//Inherit and Add Serialization
class tROIpt: public cv::Point
{
public:
tROIpt():cv::Point(){};
// This method lets cereal know which data members to serialize
template<class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(x)); // serialize things by passing them to the archive
archive(CEREAL_NVP(y)); // serialize things by passing them to the archive
}
};
/// \typedef ltROI Custom ROIs
/// \brief Tracker Region of interest - used to define vials
typedef struct tRoi
{
enum RoiType {Circle, Polygon};
RoiType mType;
std::vector<cv::Point> vPoints;
cv::Scalar mColor = CV_RGB(255,5,5);
unsigned int radius;
public:
tRoi(); //Constructor
inline int x()
{
return centre().x;
}
inline int y()
{
return centre().y;
}
inline unsigned int width()
{
return radius;
}
inline cv::Point centre() const
{
if (mType == RoiType::Circle)
return vPoints[0];
else{//Calc Centroid of Polygon
cv::Moments moments = cv::moments(vPoints);
cv::Point centroid;
centroid.x = moments.m10/moments.m00;
centroid.y = moments.m01/moments.m00;
}
}
//Construct A Circular ROI given 2 points
tRoi(cv::Point a, cv::Point b)
{
mType = RoiType::Circle;
vPoints.push_back(a);
radius = cv::norm(b - a);
}
//Construct a polygon Roi Given A list of Points
tRoi(std::vector<cv::Point>& pvPoints )
{
mType = RoiType::Polygon;
vPoints = pvPoints; //local Copy of Points
//Find the centre of this ROI
//cv::Moments mm = cv::moments(vPoints);
//centre.x = mm.m10/mm.m00;
//centre.y = mm.m01/mm.m00;
}
void draw(cv::Mat& frame)
{
if (mType == RoiType::Circle)
{
// centre = vPoints[0]; //Sync Centre To Unique data point for this ROI
cv::circle(frame,centre(),radius,cv::Scalar(0,0,250),2);
}
if (mType == RoiType::Polygon)
{
//polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar& color, int thickness=1, int lineType=8, int shift=0 )¶
cv::polylines(frame,vPoints,true,mColor,1);
//Draw Anchor points
for (std::vector<cv::Point>::iterator it = vPoints.begin() ; it != vPoints.end(); ++it)
{
cv::circle(frame,*it,1,cv::Scalar(0,0,250),2);
}
}
}
void drawMask(cv::Mat& frame)
{
if (mType == RoiType::Circle)
{
//cv::circle(frame,centre,radius,cv::Scalar(0,0,250),2);
cv::circle(frame,centre(),radius,CV_RGB(255,255,255),-1);
}
if (mType == RoiType::Polygon)
{
//void fillPoly(Mat& img, const Point** pts, const int* npts, int ncontours, const Scalar& color, int lineType=8, int shift=0, Point offset=Point() )¶
//void fillConvexPoly(Mat& img, const Point* pts, int npts, const Scalar& color, int lineType=8, int shift=0)
cv::fillConvexPoly(frame,vPoints,CV_RGB(255,255,255));
// //Draw Anchor points
// for (std::vector<cv::Point>::iterator it = vPoints.begin() ; it != vPoints.end(); ++it)
// {
// cv::circle(frame,*it,1,cv::Scalar(0,0,250),2);
// }
}
}
// Check If In Point Is Within ROI - Assuming Certain Size So as to Make A soft Boundary
bool contains(cv::Point pt,double objSize = 1)
{
if (mType == RoiType::Circle)
return (cv::norm(pt - vPoints[0]) <= (radius+objSize));
if (mType == RoiType::Polygon) //Check Distance On OUtside Is greater Than Obj Size - Only when objSize Param Is > 1
return (cv::pointPolygonTest(vPoints,pt,(objSize > 1)) > -objSize );
return false;
}
bool operator ==(const tRoi& c2)
{
if (c2.mType == RoiType::Circle)
return (centre() == c2.centre() && radius == c2.radius);
}
// This method lets cereal know which data members to serialize
template<class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(vPoints)); // serialize things by passing them to the archive
archive(CEREAL_NVP(radius)); // serialize things by passing them to the archive
}
} ltROI; //Object to define region of interest
//Need to register As archivable classes
//CEREAL_REGISTER_TYPE(ltROI);
//CEREAL_REGISTER_TYPE(tROIpt);
/// \typedef ltROIlist
///
typedef std::vector<ltROI> ltROIlist;
void addROI(ltROI& newRoi);
void deleteROI(cv::Point mousePos);
/// \fn Draw the Regions on the frame image
void drawAllROI(cv::Mat& frame);
void drawUserDefinedPoints(cv::Mat& frame);
/// \fn ltROI* ltGetFirstROIContainingPoint(ltROIlist& vRoi, cv::Point pnt)
/// \brief Loop Over ROI
/// \params vRoi list
/// \params pnt to check membership for
ltROI* ltGetFirstROIContainingPoint(ltROIlist& vRoi ,cv::Point pnt,float objectRadius );
// Check if point is contained in any ROI found int the global list of ROIs
bool pointIsInROI(cv::Point pt,float objectRadius ); //
#endif // LTROI_H