5#include "sfe_toolkit/sfe_core.h"
6#include "sfe_toolkit/sfe_face.h"
14#include "annotate.hpp"
17#include <unordered_map>
41 size_t &recommended_width,
42 size_t &recommended_height) {
51 std::smatch width_height;
53 std::regex(
".*w([0-9]+)h([0-9]+).*"))) {
54 recommended_width = std::stoi(width_height[1]);
55 recommended_height = std::stoi(width_height[2]);
66 SFEFaceDetectionAccuracyType::SFE_FACE_DETECT_ACCURACY_TYPE_ACCURATE,
68 utils::checkError(error);
69 recommended_width = input_size.width;
70 recommended_height = input_size.height;
75 std::cout <<
"Help: Usage of the program." << std::endl;
76 std::cout <<
"Options:" << std::endl;
77 std::cout <<
"-h: Display help." << std::endl;
78 std::cout <<
"-p: Probe image file." << std::endl;
79 std::cout <<
"-d: Path to detector solver." << std::endl;
80 std::cout <<
"-t: Detection threshold. <0,1>" << std::endl;
81 std::cout <<
"-m: Minimal face size in pixels to detect." << std::endl;
82 std::cout <<
"-x: Max face size in pixels to detect." << std::endl;
93 size_t recommended_width{};
94 size_t recommended_height{};
106 error =
sfeImageResize(image, recommended_width, recommended_height,
108 utils::checkError(error);
111 size_t detection_count = 10;
112 std::vector<SFEDetection> detected_faces(detection_count);
117 detected_faces.data(), &detection_count);
118 utils::checkError(error);
120 if (detection_count == 0) {
121 std::ostringstream oss;
122 oss <<
"Error: No face detected in the image ";
123 throw std::runtime_error(oss.str());
125 detected_faces.resize(detection_count);
127 std::cout <<
"Detected " << detection_count <<
" faces in the image."
130 return detected_faces;
135 for (
size_t i = 0; i < 16; ++i) {
136 os << std::hex << std::setw(2) << std::setfill(
'0')
137 <<
static_cast<int>(entity.
uuid[i]);
138 if (i == 3 || i == 5 || i == 7 || i == 9) {
170 os <<
"Face ID: " << tracked.
id <<
" UUID: " << tracked.
uuid
171 <<
" State: " << tracked.
state;
177std::ostream &
operator<<(std::ostream &os,
const std::vector<T> &vec) {
178 for (
auto &item : vec) {
179 os << item << std::endl;
186 size_t reserved_size = 10;
187 size_t tracked_faces_count = reserved_size;
188 size_t lost_faces_count = reserved_size;
189 size_t removed_faces_count = reserved_size;
191 std::vector<SFETracked> tracked_faces(tracked_faces_count);
192 std::vector<SFEEntity> lost_faces(lost_faces_count);
193 std::vector<SFEEntity> removed_faces(removed_faces_count);
198 tracked_faces.data(), &tracked_faces_count);
199 utils::checkError(error);
200 tracked_faces.resize(tracked_faces_count);
204 utils::checkError(error);
205 lost_faces.resize(lost_faces_count);
209 &removed_faces_count);
210 utils::checkError(error);
211 removed_faces.resize(removed_faces_count);
214 std::cout <<
"Tracked" << std::endl;
215 std::cout << tracked_faces;
216 std::cout <<
"Lost" << std::endl;
217 std::cout << lost_faces;
218 std::cout <<
"Removed" << std::endl;
219 std::cout << removed_faces;
223int main(
int argc,
char *argv[]) {
227 std::unordered_map<std::string, std::string> args;
230 for (
int i = 1; i < argc; ++i) {
231 std::string arg = argv[i];
238 if (i + 1 < argc && argv[i + 1][0] !=
'-') {
239 args[arg] = argv[++i];
241 std::cerr <<
"Option " << arg <<
" requires a value." << std::endl;
245 std::cerr <<
"Unknown option: " << arg << std::endl;
251 if (args.count(
"-p"))
253 if (args.count(
"-d"))
255 if (args.count(
"-t"))
257 if (args.count(
"-m"))
259 if (args.count(
"-x"))
262 utils::printFormatted(
"EXAMPLE PARAMETERS");
264 std::cout <<
"Probe image: " <<
image_probe << std::endl;
270 std::cout <<
"Min face size [px]: " <<
face_size_min << std::endl;
271 std::cout <<
"Max face size [px]: " <<
face_size_max << std::endl;
275 utils::printToolkitInfo();
282 utils::printFormatted(
"LOADING SOLVERS");
287 utils::checkError(error);
290 std::vector<SFEDetection> detected_faces;
292 utils::printFormatted(
"DETECT FACES");
301 error =
sfeImageDecode(image_data.data(), image_data.size(), &image);
302 utils::checkError(error);
308 detected_faces =
detectFaces(image, detector_solver);
315 utils::printFormatted(
"TRACK FACES");
317 utils::checkError(error);
324 utils::printFormatted(
"FRAME 1");
325 frame(detected_faces, tracker);
328 utils::printFormatted(
"FRAME 2");
329 frame(detected_faces, tracker);
332 detected_faces.clear();
335 utils::printFormatted(
"FRAME 3");
336 frame(detected_faces, tracker);
339 utils::printFormatted(
"FRAME 4");
340 frame(detected_faces, tracker);
342 utils::printFormatted(
"FINISHED");
void getRecommendedImageSize(const std::string &solver_face_detect, SFEImage &image, const size_t face_size_min, const size_t face_size_max, size_t &recommended_width, size_t &recommended_height)
Get recommended image size for face detection.
std::string solver_face_detect
Solvers to use in example, the defaults are filled in by CMake.
float detection_threshold
const auto SOLVER_PARAMETERS
size_t face_size_min
Required size of the face to be detected.
std::vector< SFEDetection > detectFaces(SFEImage &image, SFESolver &detector_solver)
Detect faces in the image.
void frame(std::vector< SFEDetection > &detections, SFETracker tracker)
Print out the results of the face tracking.
std::ostream & operator<<(std::ostream &os, const SFEEntity &entity)
Print UUID.
void sfeSolverFree(SFESolver solver)
Free memory associated with SFESolver.
SFEError sfeDetectionTrackerCreate(float new_track_threshold, float track_high_threshold, float track_low_threshold, float match_threshold, uint64_t max_time_lost, SFETracker *out_tracker)
Create a new tracker.
SFEError sfeImageResize(SFEImageView image, size_t width, size_t height, SFEImage *out_image)
Resize image.
SFEError sfeDetectionTrackerUpdate(SFETracker tracker, const SFEDetection *detections, size_t detections_count, SFETracked *out_tracked, size_t *in_out_tracked_count)
Update the tracker.
SFEError sfeDetectionTrackerRemoved(SFETracker tracker, SFEEntity *out_entities, size_t *in_out_entities_count)
Get removed entities after update.
void * SFESolver
Solver provides an abstract interface over inference models and engines.
void * SFEError
Error type used to hold optional error message.
void sfeImageFree(SFEImage image)
Free memory associated with SFEImage.
SFEError sfeSolverCreate(const char *solver_file, const SFESolverParameter *solver_parameters, size_t solver_parameters_count, SFESolver *out_solver)
Create new solver from solver file.
void sfeDetectionTrackerFree(SFETracker tracker)
Free the tracker.
SFETrackedState
Tracked state.
@ SFE_TRACKED_STATE_REMOVED
@ SFE_TRACKED_STATE_TRACKED
SFEError sfeDetectionTrackerLost(SFETracker tracker, SFEEntity *out_entities, size_t *in_out_entities_count)
Get lost entities after update.
SFEError sfeImageDecode(const unsigned char *data, size_t data_len, SFEImage *out_image)
Decode SFEImage from raw image data of various formats. Eg. PNG, JPEG ..
SFEError sfeDetect(SFESolver solver, SFEImageView image, float threshold, SFEDetection *out_detections, size_t *in_out_detection_count)
Detect objects in the source image using unified detection API.
void * SFETracker
Tracker is a ByteTrack implementation for multi-modal tracking across multiple frames.
SFEError sfeFaceDetectInputSize(SFEImageView image, SFEFaceDetectionAccuracyType detection_mode, size_t min_face_size, size_t max_face_size, SFEDetectionInputSize *out_input_size)
Calculation of recommended input image width and height according to desired minimal and maximal size...
Core detection - tagged union containing all detection types.
Entity type, used to group templates for entity identification. This type is compatible with uuid_v4 ...
Raw owned raster image representation, HWC|BGR order.
enum SFETrackedState state
Tracking state.