5#include "sfe_toolkit/sfe_core.h"
6#include "sfe_toolkit/sfe_palm.h"
12#include "annotate.hpp"
15#include <unordered_map>
21#ifdef SOLVER_PALM_LIVENESS
22std::string solver_palm_liveness = SOLVER_PALM_LIVENESS;
30 std::cout <<
"SFEDetection{ " << std::endl;
31 std::cout <<
" confidence: " << detected_palm.
confidence << std::endl;
32 std::cout <<
" SFEBoundingBox{ " << std::endl;
33 std::cout <<
" x: " << detected_palm.
bounding_box.
x << std::endl;
34 std::cout <<
" y: " << detected_palm.
bounding_box.
y << std::endl;
37 std::cout <<
" }" << std::endl;
38 std::cout <<
" }" << std::endl;
39 std::cout << std::endl;
43 std::cout <<
"Help: Usage of the program." << std::endl;
44 std::cout <<
"Options:" << std::endl;
45 std::cout <<
"-h: Display help." << std::endl;
46 std::cout <<
"-p: Probe image file." << std::endl;
47 std::cout <<
"-d: Path to detector solver." << std::endl;
48 std::cout <<
"-i: Path to liveness solver." << std::endl;
49 std::cout <<
"-t: Palm detection threshold. <0,1>" << std::endl;
53int main(
int argc,
char *argv[]) {
57 std::unordered_map<std::string, std::string> args;
60 for (
int i = 1; i < argc; ++i) {
61 std::string arg = argv[i];
68 if (i + 1 < argc && argv[i + 1][0] !=
'-') {
69 args[arg] = argv[++i];
71 std::cerr <<
"Option " << arg <<
" requires a value." << std::endl;
75 std::cerr <<
"Unknown option: " << arg << std::endl;
86 solver_palm_liveness = args[
"-i"];
90 utils::printFormatted(
"PARAMETERS");
92 std::cout <<
"Probe image: " <<
image_probe << std::endl;
96 std::cout <<
"Palm liveness solver: " << solver_palm_liveness << std::endl;
102 utils::printToolkitInfo();
111 utils::printFormatted(
"LOADING solvers");
116 utils::checkError(error);
122 utils::checkError(error);
129 utils::printFormatted(
"PALM DETECTION");
135 error =
sfeImageDecode(image_data.data(), image_data.size(), &image);
136 utils::checkError(error);
142 size_t detection_count = 1;
145 &detected_palm, &detection_count);
146 utils::checkError(error);
148 if (detection_count == 0) {
149 std::cout <<
"No palm detected in the probe image." << std::endl;
152 std::cout <<
"Found " << detection_count
153 <<
" palm(s) in the probe image. Using the palm with highest "
163 float liveness_score = 0.0f;
165 utils::printFormatted(
"LIVENESS CHECK");
168 utils::checkError(error);
172 std::cout <<
"Liveness score is " << liveness_score;
174 static const float LIVENESS_THRESHOLD = 0.8189f;
175 if (liveness_score < LIVENESS_THRESHOLD) {
176 std::cout <<
" which is below " << LIVENESS_THRESHOLD
177 <<
" threshold. Palm is spoof." << std::endl;
179 std::cout <<
" which is above " << LIVENESS_THRESHOLD
180 <<
" threshold. Palm is genuine." << std::endl;
186 std::stringstream label;
187 label <<
"Palm" << std::fixed << std::setprecision(2)
188 <<
" d:" << detected_palm.
confidence <<
" l:" << liveness_score;
190 annotate::labelBox(image, label.str(), detected_palm.
bounding_box,
191 annotate::WHITE, annotate::GREEN);
194 size_t size = image.width * image.height * 3;
195 auto png_file = std::vector<unsigned char>(size);
197 utils::checkError(error);
198 png_file.resize(size);
199 utils::saveFile(
"palm_liveness.png", png_file);
201 std::cout << std::endl;
202 std::cout <<
"Annotated image saved to palm_liveness.png" << std::endl;
204 utils::printFormatted(
"FINISHED");
float detection_threshold
const auto SOLVER_PARAMETERS
std::string solver_palm_detect
Solvers to use in example, the defaults are filled in by CMake.
void printPalmDetectionInfo(SFEDetection &detected_palm)
void sfeSolverFree(SFESolver solver)
Free memory associated with SFESolver.
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.
@ SFE_IMAGE_FORMAT_PNG
Portable Network Graphics format.
SFEError sfeImageEncode(SFEImageView image, SFEImageFormat image_format, unsigned char *out_data, size_t *in_out_data_len)
Encode SFEImage into a buffer with specified image_format.
SFEError sfeSolverCreate(const char *solver_file, const SFESolverParameter *solver_parameters, size_t solver_parameters_count, SFESolver *out_solver)
Create new solver from solver file.
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.
SFEError sfePalmLivenessPassive(SFESolver solver, SFEImageView image, const SFEDetection *detection, float *out_liveness_score)
Passive liveness score calculation.
float y
Y coordinate of the top left corner of the bounding box relative to source image size - range <0,...
float width
Width of the bounding box relative to source image size - range <0,1>
float x
X coordinate of the top left corner of the bounding box relative to source image size - range <0,...
float height
Height of the bounding box relative to source image size - range <0,1>
Core detection - tagged union containing all detection types.
SFEBoundingBox bounding_box
Bounding box (common for all detection types)
float confidence
Detection confidence - range <0,1> (common for all detection types)
Raw owned raster image representation, HWC|BGR order.