Skip to content

Commit

Permalink
Separate detector data from face-detector-dlib-hog
Browse files Browse the repository at this point in the history
  • Loading branch information
norihiro committed Apr 26, 2023
1 parent 3a1deee commit d6a776c
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 16 deletions.
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ option(WITH_PTZ_TCP "Enable to connect PTZ camera through TCP socket" ON)
option(ENABLE_MONITOR_USER "Enable monitor source for user" OFF)
option(ENABLE_DEBUG_DATA "Enable property to save error and control data" OFF)
option(WITH_DOCK "Enable dock" ON)
option(ENABLE_DATAGEN "Enable generating data" OFF)

set(CMAKE_PREFIX_PATH "${QTDIR}")
set(CMAKE_AUTOMOC ON)
Expand Down Expand Up @@ -139,3 +140,12 @@ endif()
setup_plugin_target(${CMAKE_PROJECT_NAME})

configure_file(installer/installer-macOS.pkgproj.in installer-macOS.generated.pkgproj)

if(ENABLE_DATAGEN)
add_executable(face-detector-dlib-hog-datagen
src/face-detector-dlib-hog-datagen.cpp
)
target_link_libraries(face-detector-dlib-hog-datagen
dlib
)
endif()
10 changes: 10 additions & 0 deletions src/face-detector-dlib-hog-datagen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "plugin-macros.generated.h"
#include <iostream>
#include <dlib/image_processing/frontal_face_detector.h>

int main()
{
std::cout << dlib::get_serialized_frontal_faces();
return 0;
}

50 changes: 35 additions & 15 deletions src/face-detector-dlib-hog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ struct face_detector_dlib_private_s
{
std::shared_ptr<texture_object> tex;
std::vector<rect_s> rects;
dlib::frontal_face_detector *detector;
dlib::frontal_face_detector detector;
bool detector_loaded = false;
bool has_error = false;
std::string model_filename;
int crop_l = 0, crop_r = 0, crop_t = 0, crop_b = 0;
int n_error = 0;
face_detector_dlib_private_s()
{
detector = NULL;
}
~face_detector_dlib_private_s()
{
if (detector)
delete detector;
}
};

Expand Down Expand Up @@ -89,18 +89,30 @@ void face_detector_dlib_hog::detect_main()
p->n_error--;
}

if (!p->detector)
p->detector = new dlib::frontal_face_detector(dlib::get_frontal_face_detector());
if (!p->detector_loaded) {
p->detector_loaded = true;
try {
blog(LOG_INFO, "loading file '%s'", p->model_filename.c_str());
dlib::deserialize(p->model_filename.c_str()) >> p->detector;
p->has_error = false;
}
catch(...) {
blog(LOG_ERROR, "failed to load file '%s'", p->model_filename.c_str());
p->has_error = true;
}
}

std::vector<dlib::rectangle> dets = (*p->detector)(img);
p->rects.resize(dets.size());
for (size_t i=0; i<dets.size(); i++) {
rect_s &r = p->rects[i];
r.x0 = (dets[i].left() + x0) * p->tex->scale;
r.y0 = (dets[i].top() + y0) * p->tex->scale;
r.x1 = (dets[i].right() + x0) * p->tex->scale;
r.y1 = (dets[i].bottom() + y0) * p->tex->scale;
r.score = 1.0; // TODO: implement me
if (!p->has_error) {
std::vector<dlib::rectangle> dets = p->detector(img);
p->rects.resize(dets.size());
for (size_t i=0; i<dets.size(); i++) {
rect_s &r = p->rects[i];
r.x0 = (dets[i].left() + x0) * p->tex->scale;
r.y0 = (dets[i].top() + y0) * p->tex->scale;
r.x1 = (dets[i].right() + x0) * p->tex->scale;
r.y1 = (dets[i].bottom() + y0) * p->tex->scale;
r.score = 1.0; // TODO: implement me
}
}

p->tex.reset();
Expand All @@ -110,3 +122,11 @@ void face_detector_dlib_hog::get_faces(std::vector<struct rect_s> &rects)
{
rects = p->rects;
}

void face_detector_dlib_hog::set_model(const char *filename)
{
if (p->model_filename != filename) {
p->model_filename = filename;
p->detector_loaded = false;
}
}
2 changes: 2 additions & 0 deletions src/face-detector-dlib-hog.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ class face_detector_dlib_hog : public face_detector_base
virtual ~face_detector_dlib_hog();
void set_texture(std::shared_ptr<texture_object> &, int crop_l, int crop_r, int crop_t, int crop_b) override;
void get_faces(std::vector<struct rect_s> &) override;

void set_model(const char *filename);
};
17 changes: 16 additions & 1 deletion src/face-tracker-manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define debug_detect(fmt, ...)
#define debug_track_thread(fmt, ...) // blog(LOG_INFO, fmt, __VA_ARGS__)

#define DIR_DLIB_HOG "dlib_hog_model"
#define DIR_DLIB_CNN "dlib_cnn_model"
#define DIR_DLIB_LANDMARK "dlib_face_landmark_model"

Expand Down Expand Up @@ -189,7 +190,11 @@ inline void face_tracker_manager::stage_to_detector()
detect->set_texture(cvtex,
detector_crop_l, detector_crop_r,
detector_crop_t, detector_crop_b );
if (detector_engine == engine_dlib_cnn) {
if (detector_engine == engine_dlib_hog) {
if (auto *d = dynamic_cast<face_detector_dlib_hog*>(detect))
d->set_model(detector_dlib_hog_model.c_str());
}
else if (detector_engine == engine_dlib_cnn) {
if (auto *d = dynamic_cast<face_detector_dlib_cnn*>(detect))
d->set_model(detector_dlib_cnn_model.c_str());
}
Expand Down Expand Up @@ -376,6 +381,7 @@ void face_tracker_manager::update(obs_data_t *settings)
auto _detector_engine = (enum detector_engine_e)obs_data_get_int(settings, "detector_engine");
if (_detector_engine != detector_engine)
update_detector(this, _detector_engine);
detector_dlib_hog_model = obs_data_get_string(settings, "detector_dlib_hog_model");
detector_dlib_cnn_model = obs_data_get_string(settings, "detector_dlib_cnn_model");
detector_crop_l = obs_data_get_int(settings, "detector_crop_l");
detector_crop_r = obs_data_get_int(settings, "detector_crop_r");
Expand Down Expand Up @@ -414,6 +420,8 @@ void face_tracker_manager::get_properties(obs_properties_t *pp)
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_list_add_int(p, obs_module_text("Detector.dlib.hog"), (int)engine_dlib_hog);
obs_property_list_add_int(p, obs_module_text("Detector.dlib.cnn"), (int)engine_dlib_cnn);
obs_properties_add_path(pp, "detector_dlib_hog_model", obs_module_text("Dlib HOG model"),
OBS_PATH_FILE, "Data Files (*.dat);;" "All Files (*.*)", (data_path + "/" DIR_DLIB_CNN).c_str() );
obs_properties_add_path(pp, "detector_dlib_cnn_model", obs_module_text("Dlib CNN model"),
OBS_PATH_FILE, "Data Files (*.dat);;" "All Files (*.*)", (data_path + "/" DIR_DLIB_CNN).c_str() );
obs_properties_add_int(pp, "detector_crop_l", obs_module_text("Crop left for detector"), 0, 1920, 1);
Expand Down Expand Up @@ -445,6 +453,13 @@ void face_tracker_manager::get_defaults(obs_data_t *settings)
obs_data_set_default_bool(settings, "tracking_th_en", true);
obs_data_set_default_double(settings, "tracking_th_dB", -80.0);

if (char *f = obs_module_file(DIR_DLIB_HOG "/frontal_face_detector.dat")) {
obs_data_set_default_string(settings, "detector_dlib_hog_model", f);
bfree(f);
} else {
blog(LOG_ERROR, "frontal_face_detector.dat is not found in the data directory.");
}

if (char *f = obs_module_file(DIR_DLIB_CNN "/mmod_human_face_detector.dat")) {
obs_data_set_default_string(settings, "detector_dlib_cnn_model", f);
bfree(f);
Expand Down
1 change: 1 addition & 0 deletions src/face-tracker-manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class face_tracker_manager
volatile bool reset_requested;
float tracking_threshold;
enum detector_engine_e detector_engine = engine_uninitialized;
std::string detector_dlib_hog_model;
std::string detector_dlib_cnn_model;
int detector_crop_l, detector_crop_r, detector_crop_t, detector_crop_b;
char *landmark_detection_data;
Expand Down

0 comments on commit d6a776c

Please sign in to comment.