Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
ad7cf584
Commit
ad7cf584
authored
Apr 19, 2017
by
Vladislav Sovrasov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
highgui: add ROI selector
parent
2922738b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
243 additions
and
56 deletions
+243
-56
CMakeLists.txt
modules/highgui/CMakeLists.txt
+1
-0
highgui.hpp
modules/highgui/include/opencv2/highgui.hpp
+38
-0
roiSelector.cpp
modules/highgui/src/roiSelector.cpp
+203
-0
planar_tracking.cpp
...torial_code/features2D/AKAZE_tracking/planar_tracking.cpp
+1
-1
utils.h
samples/cpp/tutorial_code/features2D/AKAZE_tracking/utils.h
+0
-55
No files found.
modules/highgui/CMakeLists.txt
View file @
ad7cf584
...
...
@@ -22,6 +22,7 @@ set(highgui_hdrs
set
(
highgui_srcs
${
CMAKE_CURRENT_LIST_DIR
}
/src/window.cpp
${
CMAKE_CURRENT_LIST_DIR
}
/src/roiSelector.cpp
)
file
(
GLOB highgui_ext_hdrs
...
...
modules/highgui/include/opencv2/highgui.hpp
View file @
ad7cf584
...
...
@@ -468,6 +468,44 @@ Mouse-wheel events are currently supported only on Windows.
*/
CV_EXPORTS
int
getMouseWheelDelta
(
int
flags
);
/** @brief Selects ROI on the given image.
Function creates a window and allows user to select a ROI using mouse.
Controls: use `space` or `enter` to finish selection, use key `c` to cancel selection (function will return the zero cv::Rect).
@param windowName name of the window where selection process will be shown.
@param img image to select a ROI.
@param showCrosshair if true crosshair of selection rectangle will be shown.
@param fromCenter if true center of selection will match initial mouse position. In opposite case a corner of
selection rectangle will correspont to the initial mouse position.
@return selected ROI or empty rect if selection canceled.
@note The function sets it's own mouse callback for specified window using cv::setMouseCallback(windowName, ...).
After finish of work an empty callback will be set for the used window.
*/
CV_EXPORTS_W
Rect
selectROI
(
const
String
&
windowName
,
InputArray
img
,
bool
showCrosshair
=
true
,
bool
fromCenter
=
false
);
/** @overload
*/
CV_EXPORTS_W
Rect
selectROI
(
InputArray
img
,
bool
showCrosshair
=
true
,
bool
fromCenter
=
false
);
/** @brief Selects ROIs on the given image.
Function creates a window and allows user to select a ROIs using mouse.
Controls: use `space` or `enter` to finish current selection and start a new one,
use `ecs` to terminate multiple ROI selection process.
@param windowName name of the window where selection process will be shown.
@param img image to select a ROI.
@param boundingBoxes selected ROIs.
@param showCrosshair if true crosshair of selection rectangle will be shown.
@param fromCenter if true center of selection will match initial mouse position. In opposite case a corner of
selection rectangle will correspont to the initial mouse position.
@note The function sets it's own mouse callback for specified window using cv::setMouseCallback(windowName, ...).
After finish of work an empty callback will be set for the used window.
*/
CV_EXPORTS_W
void
selectROIs
(
const
String
&
windowName
,
InputArray
img
,
CV_OUT
std
::
vector
<
Rect
>&
boundingBoxes
,
bool
showCrosshair
=
true
,
bool
fromCenter
=
false
);
/** @brief Creates a trackbar and attaches it to the specified window.
The function createTrackbar creates a trackbar (a slider or range control) with the specified name
...
...
modules/highgui/src/roiSelector.cpp
0 → 100644
View file @
ad7cf584
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include <opencv2/imgproc.hpp>
#include <algorithm>
using
namespace
cv
;
namespace
{
class
ROISelector
{
public
:
Rect
select
(
const
String
&
windowName
,
Mat
img
,
bool
showCrossair
=
true
,
bool
fromCenter
=
true
)
{
// show notice to user
printf
(
"Select a ROI and then press SPACE or ENTER button!
\n
"
);
printf
(
"Cancel the selection process by pressing c button!
\n
"
);
key
=
0
;
imageSize
=
img
.
size
();
// set the drawing mode
selectorParams
.
drawFromCenter
=
fromCenter
;
// show the image and give feedback to user
imshow
(
windowName
,
img
);
// copy the data, rectangle should be drawn in the fresh image
selectorParams
.
image
=
img
.
clone
();
// select the object
setMouseCallback
(
windowName
,
mouseHandler
,
(
void
*
)
this
);
// end selection process on SPACE (32) ESC (27) or ENTER (13)
while
(
!
(
key
==
32
||
key
==
27
||
key
==
13
))
{
// draw the selected object
rectangle
(
selectorParams
.
image
,
selectorParams
.
box
,
Scalar
(
255
,
0
,
0
),
2
,
1
);
// draw cross air in the middle of bounding box
if
(
showCrossair
)
{
// horizontal line
line
(
selectorParams
.
image
,
Point
((
int
)
selectorParams
.
box
.
x
,
(
int
)(
selectorParams
.
box
.
y
+
selectorParams
.
box
.
height
/
2
)),
Point
((
int
)(
selectorParams
.
box
.
x
+
selectorParams
.
box
.
width
),
(
int
)(
selectorParams
.
box
.
y
+
selectorParams
.
box
.
height
/
2
)),
Scalar
(
255
,
0
,
0
),
2
,
1
);
// vertical line
line
(
selectorParams
.
image
,
Point
((
int
)(
selectorParams
.
box
.
x
+
selectorParams
.
box
.
width
/
2
),
(
int
)
selectorParams
.
box
.
y
),
Point
((
int
)(
selectorParams
.
box
.
x
+
selectorParams
.
box
.
width
/
2
),
(
int
)(
selectorParams
.
box
.
y
+
selectorParams
.
box
.
height
)),
Scalar
(
255
,
0
,
0
),
2
,
1
);
}
// show the image bouding box
imshow
(
windowName
,
selectorParams
.
image
);
// reset the image
selectorParams
.
image
=
img
.
clone
();
// get keyboard event
key
=
waitKey
(
30
);
if
(
key
==
'c'
||
key
==
'C'
)
//cancel selection
{
selectorParams
.
box
=
Rect
();
break
;
}
}
//cleanup callback
setMouseCallback
(
windowName
,
emptyMouseHandler
,
NULL
);
return
selectorParams
.
box
;
}
void
select
(
const
String
&
windowName
,
Mat
img
,
std
::
vector
<
Rect
>
&
boundingBoxes
,
bool
showCrosshair
=
true
,
bool
fromCenter
=
true
)
{
printf
(
"Finish the selection process by pressing ESC button!
\n
"
);
boundingBoxes
.
clear
();
key
=
0
;
// while key is not ESC (27)
for
(;;)
{
Rect
temp
=
select
(
windowName
,
img
,
showCrosshair
,
fromCenter
);
if
(
key
==
27
)
break
;
if
(
temp
.
width
>
0
&&
temp
.
height
>
0
)
boundingBoxes
.
push_back
(
temp
);
}
}
struct
handlerT
{
// basic parameters
bool
isDrawing
;
Rect2d
box
;
Mat
image
;
// parameters for drawing from the center
bool
drawFromCenter
;
Point2f
center
;
// initializer list
handlerT
()
:
isDrawing
(
false
),
drawFromCenter
(
true
){};
}
selectorParams
;
private
:
static
void
emptyMouseHandler
(
int
,
int
,
int
,
int
,
void
*
)
{
}
static
void
mouseHandler
(
int
event
,
int
x
,
int
y
,
int
flags
,
void
*
param
)
{
ROISelector
*
self
=
static_cast
<
ROISelector
*>
(
param
);
self
->
opencv_mouse_callback
(
event
,
x
,
y
,
flags
);
}
void
opencv_mouse_callback
(
int
event
,
int
x
,
int
y
,
int
)
{
switch
(
event
)
{
// update the selected bounding box
case
EVENT_MOUSEMOVE
:
if
(
selectorParams
.
isDrawing
)
{
if
(
selectorParams
.
drawFromCenter
)
{
selectorParams
.
box
.
width
=
2
*
(
x
-
selectorParams
.
center
.
x
);
selectorParams
.
box
.
height
=
2
*
(
y
-
selectorParams
.
center
.
y
);
selectorParams
.
box
.
x
=
std
::
min
(
std
::
max
(
selectorParams
.
center
.
x
-
selectorParams
.
box
.
width
/
2.0
,
0.
),
(
double
)
imageSize
.
width
);
selectorParams
.
box
.
y
=
std
::
min
(
std
::
max
(
selectorParams
.
center
.
y
-
selectorParams
.
box
.
height
/
2.0
,
0.
),
(
double
)
imageSize
.
height
);
}
else
{
selectorParams
.
box
.
width
=
std
::
max
(
std
::
min
(
x
-
selectorParams
.
box
.
x
,
(
double
)
imageSize
.
width
-
selectorParams
.
box
.
x
),
-
selectorParams
.
box
.
x
);
selectorParams
.
box
.
height
=
std
::
max
(
std
::
min
(
y
-
selectorParams
.
box
.
y
,
(
double
)
imageSize
.
height
-
selectorParams
.
box
.
y
),
-
selectorParams
.
box
.
y
);
}
}
break
;
// start to select the bounding box
case
EVENT_LBUTTONDOWN
:
selectorParams
.
isDrawing
=
true
;
selectorParams
.
box
=
Rect2d
(
x
,
y
,
0
,
0
);
selectorParams
.
center
=
Point2f
((
float
)
x
,
(
float
)
y
);
break
;
// cleaning up the selected bounding box
case
EVENT_LBUTTONUP
:
selectorParams
.
isDrawing
=
false
;
if
(
selectorParams
.
box
.
width
<
0
)
{
selectorParams
.
box
.
x
+=
selectorParams
.
box
.
width
;
selectorParams
.
box
.
width
*=
-
1
;
}
if
(
selectorParams
.
box
.
height
<
0
)
{
selectorParams
.
box
.
y
+=
selectorParams
.
box
.
height
;
selectorParams
.
box
.
height
*=
-
1
;
}
break
;
}
}
// save the keypressed characted
int
key
;
Size
imageSize
;
};
}
Rect
cv
::
selectROI
(
InputArray
img
,
bool
showCrosshair
,
bool
fromCenter
)
{
ROISelector
selector
;
return
selector
.
select
(
"ROI selector"
,
img
.
getMat
(),
showCrosshair
,
fromCenter
);
}
Rect
cv
::
selectROI
(
const
String
&
windowName
,
InputArray
img
,
bool
showCrosshair
,
bool
fromCenter
)
{
ROISelector
selector
;
return
selector
.
select
(
windowName
,
img
.
getMat
(),
showCrosshair
,
fromCenter
);
}
void
cv
::
selectROIs
(
const
String
&
windowName
,
InputArray
img
,
std
::
vector
<
Rect
>&
boundingBox
,
bool
showCrosshair
,
bool
fromCenter
)
{
ROISelector
selector
;
selector
.
select
(
windowName
,
img
.
getMat
(),
boundingBox
,
showCrosshair
,
fromCenter
);
}
samples/cpp/tutorial_code/features2D/AKAZE_tracking/planar_tracking.cpp
View file @
ad7cf584
...
...
@@ -159,7 +159,7 @@ int main(int argc, char **argv)
cout
<<
"Please select a bounding box, and press any key to continue."
<<
endl
;
vector
<
Point2f
>
bb
;
cv
::
Rect
2d
uBox
=
selectROI
(
video_name
,
frame
);
cv
::
Rect
uBox
=
cv
::
selectROI
(
video_name
,
frame
);
bb
.
push_back
(
cv
::
Point2f
(
static_cast
<
float
>
(
uBox
.
x
),
static_cast
<
float
>
(
uBox
.
y
)));
bb
.
push_back
(
cv
::
Point2f
(
static_cast
<
float
>
(
uBox
.
x
+
uBox
.
width
),
static_cast
<
float
>
(
uBox
.
y
)));
bb
.
push_back
(
cv
::
Point2f
(
static_cast
<
float
>
(
uBox
.
x
+
uBox
.
width
),
static_cast
<
float
>
(
uBox
.
y
+
uBox
.
height
)));
...
...
samples/cpp/tutorial_code/features2D/AKAZE_tracking/utils.h
View file @
ad7cf584
...
...
@@ -56,59 +56,4 @@ vector<Point2f> Points(vector<KeyPoint> keypoints)
}
return
res
;
}
Rect2d
selectROI
(
const
String
&
video_name
,
const
Mat
&
frame
)
{
struct
Data
{
Point
center
;
Rect2d
box
;
static
void
mouseHandler
(
int
event
,
int
x
,
int
y
,
int
flags
,
void
*
param
)
{
Data
*
data
=
(
Data
*
)
param
;
switch
(
event
)
{
// start to select the bounding box
case
EVENT_LBUTTONDOWN
:
data
->
box
=
cvRect
(
x
,
y
,
0
,
0
);
data
->
center
=
Point2f
((
float
)
x
,(
float
)
y
);
break
;
// update the selected bounding box
case
EVENT_MOUSEMOVE
:
if
(
flags
==
1
)
{
data
->
box
.
width
=
2
*
(
x
-
data
->
center
.
x
);
data
->
box
.
height
=
2
*
(
y
-
data
->
center
.
y
);
data
->
box
.
x
=
data
->
center
.
x
-
data
->
box
.
width
/
2
.
0
;
data
->
box
.
y
=
data
->
center
.
y
-
data
->
box
.
height
/
2
.
0
;
}
break
;
// cleaning up the selected bounding box
case
EVENT_LBUTTONUP
:
if
(
data
->
box
.
width
<
0
)
{
data
->
box
.
x
+=
data
->
box
.
width
;
data
->
box
.
width
*=
-
1
;
}
if
(
data
->
box
.
height
<
0
)
{
data
->
box
.
y
+=
data
->
box
.
height
;
data
->
box
.
height
*=
-
1
;
}
break
;
}
}
}
data
;
setMouseCallback
(
video_name
,
Data
::
mouseHandler
,
&
data
);
while
(
waitKey
(
1
)
<
0
)
{
Mat
draw
=
frame
.
clone
();
rectangle
(
draw
,
data
.
box
,
Scalar
(
255
,
0
,
0
),
2
,
1
);
imshow
(
video_name
,
draw
);
}
return
data
.
box
;
}
#endif // UTILS_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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