Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
MPAI-Private
MPAI-CAE
arp
Video Analyzer
Commits
8f5a80ed
Commit
8f5a80ed
authored
Jun 04, 2023
by
Matteo
Browse files
major refactoring
parent
df88fb26
Changes
25
Expand all
Hide whitespace changes
Inline
Side-by-side
src/lib/time.cpp
View file @
8f5a80ed
#include
"time.h"
#include
"time.h
pp
"
std
::
string
getTimeLabel
(
int
ms
,
std
::
string
delim
)
{
int
mil
=
ms
%
1000
;
...
...
src/lib/time.h
→
src/lib/time.h
pp
View file @
8f5a80ed
...
...
@@ -16,4 +16,4 @@
*/
std
::
string
getTimeLabel
(
int
ms
,
std
::
string
delim
=
":"
);
#endif
\ No newline at end of file
#endif // GETTIMELABEL_H
\ No newline at end of file
src/main.cpp
View file @
8f5a80ed
This diff is collapsed.
Click to expand it.
src/utility.cpp
View file @
8f5a80ed
#include
"utility.h"
#include
"utility.h
pp
"
#include
<filesystem>
#include
<fstream>
...
...
@@ -10,134 +10,88 @@ namespace fs = std::filesystem;
using
json
=
nlohmann
::
json
;
// Constructors
utility
::
Frame
::
Frame
()
:
Mat
()
{}
utility
::
Frame
::
Frame
(
const
Mat
&
m
)
:
Mat
(
m
)
{}
utility
::
Frame
::
Frame
(
const
Frame
&
f
)
:
Mat
(
f
)
{}
// Operators
utility
::
Frame
&
utility
::
Frame
::
operator
=
(
const
Mat
&
m
)
{
Mat
::
operator
=
(
m
);
return
*
this
;
}
utility
::
Frame
&
utility
::
Frame
::
operator
=
(
const
Frame
&
f
)
{
Mat
::
operator
=
(
f
);
return
*
this
;
}
// Methods
utility
::
Frame
utility
::
Frame
::
clone
()
const
{
return
utility
::
Frame
(
Mat
::
clone
());
}
utility
::
Frame
&
utility
::
Frame
::
downsample
(
int
factor
)
{
pyrDown
(
*
this
,
*
this
,
Size
(
size
().
width
/
factor
,
size
().
height
/
factor
));
return
*
this
;
}
utility
::
Frame
&
utility
::
Frame
::
convertColor
(
int
code
)
{
cvtColor
(
*
this
,
*
this
,
code
);
return
*
this
;
}
utility
::
Frame
utility
::
Frame
::
difference
(
Frame
&
f
)
{
return
Frame
(
utility
::
difference
(
*
this
,
f
));
}
utility
::
Frame
&
utility
::
Frame
::
crop
(
Size
rect_size
,
Point2f
center
)
{
cv
::
getRectSubPix
(
*
this
,
rect_size
,
center
,
*
this
);
return
*
this
;
}
utility
::
Frame
&
utility
::
Frame
::
warp
(
cv
::
Mat
rotationMatrix
)
{
cv
::
warpAffine
(
*
this
,
*
this
,
rotationMatrix
,
this
->
size
(),
INTER_CUBIC
);
return
*
this
;
}
pair
<
utility
::
Frame
,
utility
::
Frame
>
utility
::
Frame
::
deinterlace
()
const
{
Frame
odd_frame
(
cv
::
Mat
(
this
->
rows
/
2
,
this
->
cols
,
CV_8UC3
));
Frame
even_frame
(
cv
::
Mat
(
this
->
rows
/
2
,
this
->
cols
,
CV_8UC3
));
utility
::
separateFrame
(
*
this
,
odd_frame
,
even_frame
);
void
utility
::
detect_shape
(
Ptr
<
GeneralizedHoughGuil
>
alg
,
int
pos_thresh
,
vector
<
Vec4f
>&
positive_positions
,
Mat
&
positive_votes
,
vector
<
Vec4f
>&
negative_positions
,
Mat
&
negative_votes
,
Mat
processing_area
)
{
alg
->
setPosThresh
(
pos_thresh
);
return
make_pair
(
odd_frame
,
even_frame
);
}
void
utility
::
detectShape
(
Ptr
<
GeneralizedHoughGuil
>
alg
,
Mat
templateShape
,
int
posThresh
,
vector
<
Vec4f
>&
positivePositions
,
Mat
&
positiveVotes
,
vector
<
Vec4f
>&
negativePositions
,
Mat
&
negativeVotes
,
Mat
processingArea
)
{
alg
->
setPosThresh
(
posThresh
);
alg
->
setTemplate
(
templateShape
);
int
oldSizePositive
=
0
;
int
i
=
0
;
int
maxVote
=
0
;
int
num_prev_matches
=
0
;
int
threshold_increment
=
0
;
int
max_match_score
=
0
;
// Process shapes with positive angles
alg
->
setMinAngle
(
0
);
alg
->
setMaxAngle
(
3
);
while
(
true
)
{
alg
->
detect
(
processing
A
rea
,
positive
P
ositions
,
positive
V
otes
);
int
current
Size
=
positive
P
ositions
.
size
();
if
(
current
Size
==
1
)
{
alg
->
detect
(
processing
_a
rea
,
positive
_p
ositions
,
positive
_v
otes
);
int
current
_matches
=
positive
_p
ositions
.
size
();
if
(
current
_matches
==
1
||
(
current_matches
==
0
&&
num_prev_matches
==
0
)
)
{
// We detected the most interesting shape
// Impossible to find with these parameters
break
;
}
else
if
(
current
Size
==
0
&&
oldSizePositive
>
0
)
{
}
else
if
(
current
_matches
==
0
&&
num_prev_matches
>
0
)
{
// It is not possible to detect only one shape with the current
// parameters
alg
->
setPosThresh
(
posThresh
+
i
-
1
);
// Decrease position value
alg
->
detect
(
processingArea
,
positivePositions
,
positiveVotes
);
// Detect all available shapes
break
;
}
else
if
(
currentSize
==
0
&&
oldSizePositive
==
0
)
{
// Impossible to find with these parameters
alg
->
setPosThresh
(
pos_thresh
+
threshold_increment
-
1
);
// Decrease position value
alg
->
detect
(
processing_area
,
positive_positions
,
positive_votes
);
// Detect all available shapes
break
;
}
oldSizePositive
=
current
Size
;
num_prev_matches
=
current
_matches
;
// Find maximum vote
for
(
int
j
=
0
;
j
<
positive
V
otes
.
cols
/
3
;
j
++
)
{
if
(
positive
V
otes
.
at
<
int
>
(
3
*
j
)
>
max
Vote
)
maxVot
e
=
positive
V
otes
.
at
<
int
>
(
3
*
j
);
for
(
int
j
=
0
;
j
<
positive
_v
otes
.
cols
/
3
;
j
++
)
{
if
(
positive
_v
otes
.
at
<
int
>
(
3
*
j
)
>
max
_match_score
)
max_match_scor
e
=
positive
_v
otes
.
at
<
int
>
(
3
*
j
);
}
if
(
current
Size
>
10
)
{
i
+=
5
;
// To speed up computation when there are too many matches
}
else
if
(
max
Vot
e
-
(
pos
T
hresh
+
i
)
>
100
)
{
i
+=
100
;
// To speed up computation when there are few super high
// matches
if
(
current
_matches
>
10
)
{
threshold_increment
+=
5
;
// To speed up computation when there are too many matches
}
else
if
(
max
_match_scor
e
-
(
pos
_t
hresh
+
threshold_increment
)
>
100
)
{
threshold_increment
+=
100
;
// To speed up computation when there are few super high
// matches
}
else
{
i
++
;
threshold_increment
++
;
}
alg
->
setPosThresh
(
pos
T
hresh
+
i
);
alg
->
setPosThresh
(
pos
_t
hresh
+
threshold_increment
);
}
int
oldSizeNegative
=
0
;
// Reset incremental position value
i
=
0
;
maxVote
=
0
;
threshold_increment
=
0
;
num_prev_matches
=
0
;
max_match_score
=
0
;
// Process shapes with negative angles
alg
->
setMinAngle
(
357
);
alg
->
setMaxAngle
(
360
);
while
(
true
)
{
alg
->
detect
(
processing
A
rea
,
negative
P
ositions
,
negative
V
otes
);
int
current
Size
=
negative
P
ositions
.
size
();
if
(
current
Size
==
1
)
{
alg
->
detect
(
processing
_a
rea
,
negative
_p
ositions
,
negative
_v
otes
);
int
current
_matches
=
negative
_p
ositions
.
size
();
if
(
current
_matches
==
1
||
(
current_matches
==
0
&&
num_prev_matches
==
0
)
)
{
// We detected the most interesting shape
// Impossible to found with these parameters
break
;
}
else
if
(
current
Size
==
0
&&
oldSizeNegative
>
0
)
{
}
else
if
(
current
_matches
==
0
&&
num_prev_matches
>
0
)
{
// It is not possible to detect only one shape with the current
// parameters
alg
->
setPosThresh
(
posThresh
+
i
-
1
);
// Decrease position value
alg
->
detect
(
processingArea
,
negativePositions
,
negativeVotes
);
// Detect all available shapes
break
;
}
else
if
(
currentSize
==
0
&&
oldSizeNegative
==
0
)
{
// Impossible to found with these parameters
alg
->
setPosThresh
(
pos_thresh
+
threshold_increment
-
1
);
// Decrease position value
alg
->
detect
(
processing_area
,
negative_positions
,
negative_votes
);
// Detect all available shapes
break
;
}
oldSizeNegative
=
current
Size
;
num_prev_matches
=
current
_matches
;
// Find maximum vote
for
(
int
j
=
0
;
j
<
positive
V
otes
.
cols
/
3
;
j
++
)
{
if
(
positive
V
otes
.
at
<
int
>
(
3
*
j
)
>
max
Vote
)
maxVot
e
=
positive
V
otes
.
at
<
int
>
(
3
*
j
);
for
(
int
j
=
0
;
j
<
positive
_v
otes
.
cols
/
3
;
j
++
)
{
if
(
positive
_v
otes
.
at
<
int
>
(
3
*
j
)
>
max
_match_score
)
max_match_scor
e
=
positive
_v
otes
.
at
<
int
>
(
3
*
j
);
}
if
(
current
Size
>
10
)
{
i
+=
5
;
// To speed up computation when there are too many matches
}
else
if
(
max
Vot
e
-
(
pos
T
hresh
+
i
)
>
100
)
{
i
+=
100
;
// To speed up computation when there are few super high
// matches
if
(
current
_matches
>
10
)
{
threshold_increment
+=
5
;
// To speed up computation when there are too many matches
}
else
if
(
max
_match_scor
e
-
(
pos
_t
hresh
+
threshold_increment
)
>
100
)
{
threshold_increment
+=
100
;
// To speed up computation when there are few super high
// matches
}
else
{
i
++
;
threshold_increment
++
;
}
alg
->
setPosThresh
(
pos
T
hresh
+
i
);
alg
->
setPosThresh
(
pos
_t
hresh
+
threshold_increment
);
}
}
...
...
@@ -164,51 +118,6 @@ RotatedRect utility::drawShapes(Mat frame, const Vec4f& positions, Scalar color,
return
rr
;
}
void
utility
::
separateFrame
(
const
cv
::
Mat
frame
,
cv
::
Mat
&
odd_frame
,
cv
::
Mat
&
even_frame
)
{
int
i_odd_frame
=
0
;
int
i_even_frame
=
0
;
for
(
int
i
=
0
;
i
<
frame
.
rows
;
i
++
)
{
for
(
int
j
=
0
;
j
<
frame
.
cols
;
j
++
)
{
if
(
i
%
2
==
0
)
{
even_frame
.
at
<
cv
::
Vec3b
>
(
i_even_frame
,
j
)[
0
]
=
frame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
0
];
even_frame
.
at
<
cv
::
Vec3b
>
(
i_even_frame
,
j
)[
1
]
=
frame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
1
];
even_frame
.
at
<
cv
::
Vec3b
>
(
i_even_frame
,
j
)[
2
]
=
frame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
2
];
}
else
{
odd_frame
.
at
<
cv
::
Vec3b
>
(
i_odd_frame
,
j
)[
0
]
=
frame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
0
];
odd_frame
.
at
<
cv
::
Vec3b
>
(
i_odd_frame
,
j
)[
1
]
=
frame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
1
];
odd_frame
.
at
<
cv
::
Vec3b
>
(
i_odd_frame
,
j
)[
2
]
=
frame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
2
];
}
}
if
(
i
%
2
==
0
)
{
i_even_frame
++
;
}
else
{
i_odd_frame
++
;
}
}
return
;
}
cv
::
Mat
utility
::
difference
(
cv
::
Mat
&
prevFrame
,
cv
::
Mat
&
currentFrame
)
{
cv
::
Mat
diff
=
currentFrame
.
clone
();
for
(
int
i
=
0
;
i
<
currentFrame
.
rows
;
i
++
)
{
for
(
int
j
=
0
;
j
<
currentFrame
.
cols
;
j
++
)
{
if
(
prevFrame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
0
]
!=
currentFrame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
0
]
||
prevFrame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
1
]
!=
currentFrame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
1
]
||
prevFrame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
2
]
!=
currentFrame
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
2
])
{
// Different pixels
diff
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
0
]
=
0
;
}
else
{
// Identical pixels
diff
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
0
]
=
255
;
}
}
}
return
diff
;
}
Threshold
::
Threshold
(
float
percentual
,
int
angle
,
int
scale
,
int
pos
)
{
if
(
percentual
<
0
||
percentual
>
100
)
throw
std
::
invalid_argument
(
"Percentual must be between 0 and 100"
);
...
...
src/utility.h
→
src/utility.h
pp
View file @
8f5a80ed
...
...
@@ -13,87 +13,31 @@ namespace fs = std::filesystem;
/**
* @brief Namespace containing a set of utility functions used in the project.
* The functions are mainly used to perform operations on images.
*
*/
namespace
utility
{
/**
* @class Frame
* @brief Class that extends the OpenCV Mat class, adding some useful methods
* frequently used in the project.
*
*/
class
Frame
:
public
Mat
{
public:
Frame
();
Frame
(
const
Mat
&
m
);
Frame
(
const
Frame
&
f
);
Frame
&
operator
=
(
const
Mat
&
m
);
Frame
&
operator
=
(
const
Frame
&
f
);
Frame
clone
()
const
;
/**
* @brief Downsample the image by a given factor.
*
* @param factor The factor by which the image will be downsampled.
* @return Frame& The downsampled image.
*/
Frame
&
downsample
(
int
factor
);
/**
* @brief Convert the image to a given color space.
*
* @param code The code of the color space to which the image will be
* converted.
* @return Frame& The converted image.
*/
Frame
&
convertColor
(
int
code
);
Frame
difference
(
Frame
&
f
);
/**
* @brief Crop the image to a given size, centered in a given point.
*
* @param rect_size The size of the cropped image.
* @param center The center of the cropped image.
* @return Frame& The cropped image.
*/
Frame
&
crop
(
Size
rect_size
,
Point2f
center
);
/**
* @brief Warp the image using a given rotation matrix.
*
* @param rotationMatrix The rotation matrix used to warp the image.
* @return Frame& The warped image.
*/
Frame
&
warp
(
cv
::
Mat
rotationMatrix
);
/**
* @brief Deinterlace the image, returning two images, one containing the
* odd lines and the other containing the even lines.
*
* @return std::pair<Frame, Frame> The two images containing the odd and
* even lines.
*/
std
::
pair
<
Frame
,
Frame
>
deinterlace
()
const
;
};
/**
* @fn void detectShape(Ptr<GeneralizedHoughGuil> alg, Mat templateShape, int
* posThresh, vector<Vec4f> &positivePositions, Mat &positiveVotes,
* vector<Vec4f> &negativePositions, Mat &negativeVotes, Mat processingArea)
* @brief Detects a given shape in an image, using a the OpenCV algorithm
* @fn void detect_shape(Ptr<GeneralizedHoughGuil> alg, int
* pos_thresh, vector<Vec4f> &positive_positions, Mat &positive_votes,
* vector<Vec4f> &negative_positions, Mat &negative_votes, Mat processing_area)
* @brief Detects a shape in an image, using a the OpenCV algorithm
* GeneralizedHoughGuil.
*
* @param[in] alg the algorithm instance;
* @param[in]
templateShape the shape to detect;
*
@param[in] posThresh the position votes threshol
d;
* @param[out] positive
P
ositions vector representing the position assigned to
* @param[in]
pos_thresh the position votes threshold, which determines the minimum number of votes required to consider
*
a detection vali
d;
* @param[out] positive
_p
ositions vector representing the position assigned to
* each found rectangle for positive angles;
* @param[out] positive
V
otes vector representing the vote assigned to each found
* @param[out] positive
_v
otes vector representing the vote assigned to each found
* rectangle for positive angles;
* @param[out] negative
P
ositions vector representing the position assigned to
* @param[out] negative
_p
ositions vector representing the position assigned to
* each found rectangle for negative angles;
* @param[out] negative
V
otes vector representing the vote assigned to each found
* @param[out] negative
_v
otes vector representing the vote assigned to each found
* rectangle for negative angles;
* @param[in] processing
A
rea the image to be processed.
* @param[in] processing
_a
rea the image to be processed.
*/
void
detect
S
hape
(
Ptr
<
GeneralizedHoughGuil
>
alg
,
Mat
templateShape
,
int
pos
T
hresh
,
vector
<
Vec4f
>&
positive
P
ositions
,
Mat
&
positiveVotes
,
vector
<
Vec4f
>&
negative
P
ositions
,
Mat
&
negative
V
otes
,
Mat
processing
A
rea
);
void
detect
_s
hape
(
Ptr
<
GeneralizedHoughGuil
>
alg
,
int
pos
_t
hresh
,
vector
<
Vec4f
>&
positive
_p
ositions
,
Mat
&
positive_votes
,
vector
<
Vec4f
>&
negative
_p
ositions
,
Mat
&
negative
_v
otes
,
Mat
processing
_a
rea
);
/**
* @fn RotatedRect drawShapes(Mat frame, Vec4f &positions, Scalar color, int
...
...
@@ -112,29 +56,6 @@ void detectShape(Ptr<GeneralizedHoughGuil> alg, Mat templateShape, int posThresh
*/
RotatedRect
drawShapes
(
Mat
frame
,
const
Vec4f
&
positions
,
Scalar
color
,
int
width
,
int
height
,
int
offsetX
,
int
offsetY
,
float
processingScale
);
/**
* @fn void separateFrame(cv::Mat frame, cv::Mat &odd_frame, cv::Mat
* &even_frame)
* @brief Function to deinterlace the current image.
*
* @param[in] frame image to be processed;
* @param[out] odd_frame odd plane;
* @param[out] even_frame even plane.
*/
void
separateFrame
(
const
cv
::
Mat
frame
,
cv
::
Mat
&
odd_frame
,
cv
::
Mat
&
even_frame
);
/**
* @fn void separateFrame(cv::Mat frame, cv::Mat &odd_frame, cv::Mat
* &even_frame)
* @brief Compute the number of different pixels between two frames.
*
* @param prevFrame the first frame;
* @param currentFrame the second frame.
* @return cv::Mat A black and white frame, where black pixels represent a
* difference, while white pixels represent an equality.
*/
cv
::
Mat
difference
(
cv
::
Mat
&
prevFrame
,
cv
::
Mat
&
currentFrame
);
}
// namespace utility
/**
...
...
@@ -164,7 +85,7 @@ struct Threshold {
* @brief Enum containing the possible objects to detect.
*
*/
enum
ROI
{
TAPE
,
CAPSTAN
};
enum
class
ROI
{
TAPE
,
CAPSTAN
};
/**
* @struct SceneObject
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment