mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
Refactor the GUI code out
I also cleaned up a bunch of code. I'm not sure why the simple_object_detector was keeping track of the upsample amount, since it can't even be passed as an argument to the constructor. Therefore, I removed the simple_object_detector_py and the second declaration of the hog object detector. I also changed the view code to optionally take keyword args of color and added a single view of a rectangle. Finally, I added viewing of the shape parts.
This commit is contained in:
parent
697aecb420
commit
e801bd6ab5
@ -24,6 +24,7 @@ add_python_module(dlib
|
||||
src/image.cpp
|
||||
src/object_detection.cpp
|
||||
src/shape_predictor.cpp
|
||||
src/gui.cpp
|
||||
)
|
||||
|
||||
# When you run "make install" we will copy the compiled dlib.so (or dlib.pyd)
|
||||
|
@ -16,7 +16,7 @@ void bind_svm_struct();
|
||||
void bind_image_classes();
|
||||
void bind_object_detection();
|
||||
void bind_shape_predictors();
|
||||
|
||||
void bind_gui();
|
||||
|
||||
BOOST_PYTHON_MODULE(dlib)
|
||||
{
|
||||
@ -37,5 +37,6 @@ BOOST_PYTHON_MODULE(dlib)
|
||||
bind_image_classes();
|
||||
bind_object_detection();
|
||||
bind_shape_predictors();
|
||||
bind_gui();
|
||||
}
|
||||
|
||||
|
121
tools/python/src/gui.cpp
Normal file
121
tools/python/src/gui.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#ifndef DLIB_NO_GUI_SUPPORT
|
||||
|
||||
#include <dlib/python.h>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <dlib/geometry.h>
|
||||
#include <dlib/image_processing/frontal_face_detector.h>
|
||||
#include <dlib/image_processing/render_face_detections.h>
|
||||
#include <dlib/gui_widgets.h>
|
||||
|
||||
using namespace dlib;
|
||||
using namespace std;
|
||||
using namespace boost::python;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// Forward declaration of the simple_object_detector
|
||||
typedef object_detector<scan_fhog_pyramid<pyramid_down<6> > > simple_object_detector;
|
||||
|
||||
void image_window_set_image_fhog_detector (
|
||||
image_window& win,
|
||||
const frontal_face_detector& det
|
||||
)
|
||||
{
|
||||
win.set_image(draw_fhog(det));
|
||||
}
|
||||
|
||||
void image_window_set_image_simple_detector (
|
||||
image_window& win,
|
||||
const simple_object_detector& det
|
||||
)
|
||||
{
|
||||
win.set_image(draw_fhog(det));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void image_window_set_image (
|
||||
image_window& win,
|
||||
object img
|
||||
)
|
||||
{
|
||||
if (is_gray_python_image(img))
|
||||
return win.set_image(numpy_gray_image(img));
|
||||
else if (is_rgb_python_image(img))
|
||||
return win.set_image(numpy_rgb_image(img));
|
||||
else
|
||||
throw dlib::error("Unsupported image type, must be 8bit gray or RGB image.");
|
||||
}
|
||||
|
||||
void add_overlay_rect (
|
||||
image_window& win,
|
||||
const rectangle& rect,
|
||||
const rgb_pixel& color
|
||||
)
|
||||
{
|
||||
std::vector<rectangle> rects;
|
||||
rects.push_back(rect);
|
||||
win.add_overlay(rects, color);
|
||||
}
|
||||
|
||||
void add_overlay_parts (
|
||||
image_window& win,
|
||||
const full_object_detection& detection,
|
||||
const rgb_pixel& color
|
||||
)
|
||||
{
|
||||
std::vector<full_object_detection> detections;
|
||||
detections.push_back(detection);
|
||||
win.add_overlay(render_face_detections(detections, color));
|
||||
}
|
||||
|
||||
boost::shared_ptr<image_window> make_image_window_from_image(object img)
|
||||
{
|
||||
boost::shared_ptr<image_window> win(new image_window);
|
||||
image_window_set_image(*win, img);
|
||||
return win;
|
||||
}
|
||||
|
||||
boost::shared_ptr<image_window> make_image_window_from_image_and_title(object img, const string& title)
|
||||
{
|
||||
boost::shared_ptr<image_window> win(new image_window);
|
||||
image_window_set_image(*win, img);
|
||||
win->set_title(title);
|
||||
return win;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void bind_gui()
|
||||
{
|
||||
using boost::python::arg;
|
||||
{
|
||||
typedef image_window type;
|
||||
typedef void (image_window::*set_title_funct)(const std::string&);
|
||||
typedef void (image_window::*add_overlay_funct)(const std::vector<rectangle>& r, rgb_pixel p);
|
||||
class_<type,boost::noncopyable>("image_window",
|
||||
"This is a GUI window capable of showing images on the screen.")
|
||||
.def("__init__", make_constructor(&make_image_window_from_image),
|
||||
"Create an image window that displays the given numpy image.")
|
||||
.def("__init__", make_constructor(&make_image_window_from_image_and_title),
|
||||
"Create an image window that displays the given numpy image and also has the given title.")
|
||||
.def("set_image", image_window_set_image, arg("image"),
|
||||
"Make the image_window display the given image.")
|
||||
.def("set_image", image_window_set_image_fhog_detector, arg("detector"),
|
||||
"Make the image_window display the given HOG detector's filters.")
|
||||
.def("set_image", image_window_set_image_simple_detector, arg("detector"),
|
||||
"Make the image_window display the given HOG detector's filters.")
|
||||
.def("set_title", (set_title_funct)&type::set_title, arg("title"),
|
||||
"Set the title of the window to the given value.")
|
||||
.def("clear_overlay", &type::clear_overlay, "Remove all overlays from the image_window.")
|
||||
.def("add_overlay", (add_overlay_funct)&type::add_overlay<rgb_pixel>, (arg("rectangles"), arg("color")=rgb_pixel(255, 0, 0)),
|
||||
"Add a list of rectangles to the image_window. They will be displayed as red boxes by default, but the color can be passed.")
|
||||
.def("add_overlay", add_overlay_rect, (arg("rectangle"), arg("color")=rgb_pixel(255, 0, 0)),
|
||||
"Add a rectangle to the image_window. It will be displayed as a red box by default, but the color can be passed.")
|
||||
.def("add_overlay", add_overlay_parts, (arg("detection"), arg("color")=rgb_pixel(0, 0, 255)),
|
||||
"Add full_object_detection parts to the image window. They will be displayed as blue lines by default, but the color can be passed.")
|
||||
.def("wait_until_closed", &type::wait_until_closed,
|
||||
"This function blocks until the window is closed.");
|
||||
}
|
||||
}
|
||||
#endif
|
@ -6,10 +6,6 @@
|
||||
#include <boost/python/args.hpp>
|
||||
#include <dlib/geometry.h>
|
||||
#include <dlib/image_processing/frontal_face_detector.h>
|
||||
#ifndef DLIB_NO_GUI_SUPPORT
|
||||
#include <dlib/image_processing/render_face_detections.h>
|
||||
#include <dlib/gui_widgets.h>
|
||||
#endif
|
||||
#include "indexing.h"
|
||||
#include "simple_object_detector.h"
|
||||
#include "conversion.h"
|
||||
@ -52,8 +48,8 @@ string print_rectangle_repr(const rectangle& r)
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
std::vector<rectangle> run_detector (
|
||||
frontal_face_detector& detector,
|
||||
std::vector<rectangle> run_detector_with_upscale (
|
||||
simple_object_detector& detector,
|
||||
object img,
|
||||
const unsigned int upsampling_amount
|
||||
)
|
||||
@ -112,125 +108,6 @@ std::vector<rectangle> run_detector (
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct simple_object_detector_py
|
||||
{
|
||||
simple_object_detector detector;
|
||||
unsigned int upsampling_amount;
|
||||
|
||||
std::vector<rectangle> run_detector1 (object img, const unsigned int upsampling_amount_)
|
||||
{ return ::run_detector(detector, img, upsampling_amount_); }
|
||||
|
||||
std::vector<rectangle> run_detector2 (object img)
|
||||
{ return ::run_detector(detector, img, upsampling_amount); }
|
||||
};
|
||||
|
||||
void serialize (const simple_object_detector_py& item, std::ostream& out)
|
||||
{
|
||||
int version = 1;
|
||||
serialize(item.detector, out);
|
||||
serialize(version, out);
|
||||
serialize(item.upsampling_amount, out);
|
||||
}
|
||||
|
||||
void deserialize (simple_object_detector_py& item, std::istream& in)
|
||||
{
|
||||
int version = 0;
|
||||
deserialize(item.detector, in);
|
||||
deserialize(version, in);
|
||||
if (version != 1)
|
||||
throw dlib::serialization_error("Unexpected version found while deserializing a simple_object_detector.");
|
||||
deserialize(item.upsampling_amount, in);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
#ifndef DLIB_NO_GUI_SUPPORT
|
||||
void image_window_set_image_fhog_detector (
|
||||
image_window& win,
|
||||
const frontal_face_detector& det
|
||||
)
|
||||
{
|
||||
win.set_image(draw_fhog(det));
|
||||
}
|
||||
|
||||
void image_window_set_image_simple_detector (
|
||||
image_window& win,
|
||||
const simple_object_detector_py& det
|
||||
)
|
||||
{
|
||||
win.set_image(draw_fhog(det.detector));
|
||||
}
|
||||
|
||||
void image_window_set_image (
|
||||
image_window& win,
|
||||
object img
|
||||
)
|
||||
{
|
||||
if (is_gray_python_image(img))
|
||||
return win.set_image(numpy_gray_image(img));
|
||||
else if (is_rgb_python_image(img))
|
||||
return win.set_image(numpy_rgb_image(img));
|
||||
else
|
||||
throw dlib::error("Unsupported image type, must be 8bit gray or RGB image.");
|
||||
}
|
||||
|
||||
|
||||
void add_red_overlay_rects (
|
||||
image_window& win,
|
||||
const std::vector<rectangle>& rects
|
||||
)
|
||||
{
|
||||
win.add_overlay(rects, rgb_pixel(255, 0, 0));
|
||||
}
|
||||
|
||||
void add_overlay_parts (
|
||||
image_window& win,
|
||||
const object& pydetections,
|
||||
const rgb_pixel& color
|
||||
)
|
||||
{
|
||||
std::vector<full_object_detection> detections;
|
||||
extract<boost::python::list> list_check(pydetections);
|
||||
if (list_check.check())
|
||||
{
|
||||
const unsigned long num_detections = len(pydetections);
|
||||
for (unsigned long i = 0; i < num_detections; ++i)
|
||||
detections.push_back(extract<full_object_detection>(pydetections[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
detections.push_back(extract<full_object_detection>(pydetections));
|
||||
}
|
||||
win.add_overlay(render_face_detections(detections, color));
|
||||
}
|
||||
|
||||
void add_blue_overlay_parts (
|
||||
image_window& win,
|
||||
const object& pydetections
|
||||
)
|
||||
{
|
||||
add_overlay_parts(win, pydetections, rgb_pixel(0, 0, 255));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
boost::shared_ptr<image_window> make_image_window_from_image(object img)
|
||||
{
|
||||
boost::shared_ptr<image_window> win(new image_window);
|
||||
image_window_set_image(*win, img);
|
||||
return win;
|
||||
}
|
||||
|
||||
boost::shared_ptr<image_window> make_image_window_from_image_and_title(object img, const string& title)
|
||||
{
|
||||
boost::shared_ptr<image_window> win(new image_window);
|
||||
image_window_set_image(*win, img);
|
||||
win->set_title(title);
|
||||
return win;
|
||||
}
|
||||
#endif
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
inline void train_simple_object_detector_on_images_py (
|
||||
@ -471,7 +348,7 @@ ensures \n\
|
||||
metrics. "
|
||||
);
|
||||
{
|
||||
typedef simple_object_detector_py type;
|
||||
typedef simple_object_detector type;
|
||||
class_<type>("simple_object_detector",
|
||||
"This object represents a sliding window histogram-of-oriented-gradients based object detector.")
|
||||
.def("__init__", make_constructor(&load_object_from_file<type>),
|
||||
@ -481,7 +358,7 @@ train_simple_object_detector() routine."
|
||||
Loads a simple_object_detector from a file that contains the output of the
|
||||
train_simple_object_detector() routine.
|
||||
!*/)
|
||||
.def("__call__", &type::run_detector1, (arg("image"), arg("upsample_num_times")),
|
||||
.def("__call__", run_detector_with_upscale, (arg("image"), arg("upsample_num_times")=0),
|
||||
"requires \n\
|
||||
- image is a numpy ndarray containing either an 8bit grayscale or RGB \n\
|
||||
image. \n\
|
||||
@ -507,96 +384,8 @@ ensures \n\
|
||||
default will be used.
|
||||
!*/
|
||||
)
|
||||
.def("__call__", &type::run_detector2, (arg("image")),
|
||||
"requires \n\
|
||||
- image is a numpy ndarray containing either an 8bit grayscale or RGB \n\
|
||||
image. \n\
|
||||
ensures \n\
|
||||
- This function runs the object detector on the input image and returns \n\
|
||||
a list of detections. "
|
||||
/*!
|
||||
requires
|
||||
- image is a numpy ndarray containing either an 8bit grayscale or RGB
|
||||
image.
|
||||
ensures
|
||||
- This function runs the object detector on the input image and returns
|
||||
a list of detections.
|
||||
!*/
|
||||
)
|
||||
.def_pickle(serialize_pickle<type>());
|
||||
}
|
||||
|
||||
{
|
||||
typedef frontal_face_detector type;
|
||||
class_<type>("fhog_object_detector",
|
||||
"This object represents a sliding window histogram-of-oriented-gradients based object detector.")
|
||||
.def("__init__", make_constructor(&load_object_from_file<type>),
|
||||
"Loads a fhog_object_detector from a file that contains a serialized \n\
|
||||
object_detector<scan_fhog_pyramid<pyramid_down<6>>> object. " )
|
||||
.def("__call__", &::run_detector, (arg("image"), arg("upsample_num_times")=0),
|
||||
"requires \n\
|
||||
- image is a numpy ndarray containing either an 8bit \n\
|
||||
grayscale or RGB image. \n\
|
||||
- upsample_num_times >= 0 \n\
|
||||
ensures \n\
|
||||
- This function runs the object detector on the input image \n\
|
||||
and returns a list of detections. \n\
|
||||
- You can detect smaller objects by upsampling the image \n\
|
||||
before running the detector. This function can do that \n\
|
||||
for you automatically if you set upsample_num_times to a \n\
|
||||
non-zero value. Specifically, the image is doubled in \n\
|
||||
size upsample_num_times times. "
|
||||
/*!
|
||||
requires
|
||||
- image is a numpy ndarray containing either an 8bit
|
||||
grayscale or RGB image.
|
||||
- upsample_num_times >= 0
|
||||
ensures
|
||||
- This function runs the object detector on the input image
|
||||
and returns a list of detections.
|
||||
- You can detect smaller objects by upsampling the image
|
||||
before running the detector. This function can do that
|
||||
for you automatically if you set upsample_num_times to a
|
||||
non-zero value. Specifically, the image is doubled in
|
||||
size upsample_num_times times.
|
||||
!*/
|
||||
)
|
||||
.def_pickle(serialize_pickle<type>());
|
||||
}
|
||||
|
||||
#ifndef DLIB_NO_GUI_SUPPORT
|
||||
{
|
||||
typedef image_window type;
|
||||
typedef void (image_window::*set_title_funct)(const std::string&);
|
||||
typedef void (image_window::*add_overlay_funct)(const std::vector<rectangle>& r, rgb_pixel p);
|
||||
class_<type,boost::noncopyable>("image_window",
|
||||
"This is a GUI window capable of showing images on the screen.")
|
||||
.def("__init__", make_constructor(&make_image_window_from_image),
|
||||
"Create an image window that displays the given numpy image.")
|
||||
.def("__init__", make_constructor(&make_image_window_from_image_and_title),
|
||||
"Create an image window that displays the given numpy image and also has the given title.")
|
||||
.def("set_image", image_window_set_image, arg("image"),
|
||||
"Make the image_window display the given image.")
|
||||
.def("set_image", image_window_set_image_fhog_detector, arg("detector"),
|
||||
"Make the image_window display the given HOG detector's filters.")
|
||||
.def("set_image", image_window_set_image_simple_detector, arg("detector"),
|
||||
"Make the image_window display the given HOG detector's filters.")
|
||||
.def("set_title", (set_title_funct)&type::set_title, arg("title"),
|
||||
"Set the title of the window to the given value.")
|
||||
.def("clear_overlay", &type::clear_overlay, "Remove all overlays from the image_window.")
|
||||
.def("add_overlay", (add_overlay_funct)&type::add_overlay<rgb_pixel>, (arg("rectangles"), arg("color")),
|
||||
"Add a list of rectangles to the image_window. They will be displayed as boxes of the given color.")
|
||||
.def("add_overlay", add_red_overlay_rects,
|
||||
"Add a list of rectangles to the image_window. They will be displayed as red boxes.")
|
||||
.def("add_overlay", add_blue_overlay_parts,
|
||||
"Add either a single or a list of full_object_detection parts to the image window. They will be displayed as blue lines.")
|
||||
.def("add_overlay", add_overlay_parts, (arg("detections"), arg("color")),
|
||||
"Add either a single or a list of full_object_detection parts to the image window. They will be displayed as lines of the given color.")
|
||||
.def("wait_until_closed", &type::wait_until_closed,
|
||||
"This function blocks until the window is closed.");
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
typedef std::vector<rectangle> type;
|
||||
class_<type>("rectangles", "An array of rectangle objects.")
|
||||
|
Loading…
Reference in New Issue
Block a user