SmartFace Embedded Toolkit  4.2.1
Loading...
Searching...
No Matches
example_palm_attributes.cpp

Example of use of sfe_palm library

#include "sfe_toolkit/sfe_core.h"
#include "sfe_toolkit/sfe_palm.h"
#include <iomanip>
#include <optional>
#include <regex>
#include <sstream>
#include <vector>
#include "annotate.hpp"
#include "solvers.h"
#include "utils.hpp"
#include <unordered_map>
std::string image_probe = "assets/palm/palm_id1_r1.jpg";
std::string solver_palm_detect = SOLVER_PALM_DETECT;
#ifdef SOLVER_PALM_ATTRIBUTES
std::optional<std::string> solver_palm_attributes = SOLVER_PALM_ATTRIBUTES;
#else
std::optional<std::string> solver_palm_attributes = std::nullopt;
#endif // SOLVER_PALM_ATTRIBUTES
const auto SOLVER_PARAMETERS = std::vector<SFESolverParameter>{};
float detection_threshold = 0.1f;
inline void printPalmDetectionInfo(SFEDetection &detected_palm, SFEPalmLandmarks &attributes) {
std::cout << "SFEDetection{ " << std::endl;
std::cout << " confidence: " << detected_palm.confidence << std::endl;
std::cout << " hand_position: " << attributes.hand_position << std::endl;
std::cout << " hand_orientation: " << attributes.hand_orientation << std::endl;
std::cout << " SFEBoundingBox{ " << std::endl;
std::cout << " x: " << detected_palm.bounding_box.x << std::endl;
std::cout << " y: " << detected_palm.bounding_box.y << std::endl;
std::cout << " width: " << detected_palm.bounding_box.width << std::endl;
std::cout << " height: " << detected_palm.bounding_box.height << std::endl;
std::cout << " }" << std::endl;
std::cout << " Keypoints{ " << std::endl;
for (auto &keypoint : attributes.keypoints) {
std::cout << " SFEPalmKeypoint{ " << std::endl;
std::cout << " x: " << keypoint.x << std::endl;
std::cout << " y: " << keypoint.y << std::endl;
std::cout << " }" << std::endl;
}
std::cout << " }" << std::endl;
std::cout << " }" << std::endl;
std::cout << std::endl;
}
void printHelp() {
std::cout << "Help: Usage of the program." << std::endl;
std::cout << "Options:" << std::endl;
std::cout << "-h: Display help." << std::endl;
std::cout << "-p: Probe image file." << std::endl;
std::cout << "-d: Path to detector solver." << std::endl;
std::cout << "-i: Path to attributes solver." << std::endl;
std::cout << "-t: Palm detection threshold. <0,1>" << std::endl;
}
int main(int argc, char *argv[]) {
{ // STAGE: 0 Parse command line arguments
// Map to store argument values
std::unordered_map<std::string, std::string> args;
// Parse command line arguments
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg[0] == '-') {
if (arg == "-h") {
return 0;
}
// Check if there's a next argument and it isn't another option
if (i + 1 < argc && argv[i + 1][0] != '-') {
args[arg] = argv[++i];
} else {
std::cerr << "Option " << arg << " requires a value." << std::endl;
return 1;
}
} else {
std::cerr << "Unknown option: " << arg << std::endl;
return 1;
}
}
// Assign values to variables based on parsed arguments
if (args.count("-p"))
image_probe = args["-p"];
if (args.count("-d"))
solver_palm_detect = args["-d"];
if (args.count("-i"))
solver_palm_attributes = args["-i"];
if (args.count("-t"))
detection_threshold = std::stof(args["-t"]);
utils::printFormatted("PARAMETERS");
// Print resource names
std::cout << "Probe image: " << image_probe << std::endl;
// Print solver names
std::cout << "Palm detection solver: " << solver_palm_detect << std::endl;
std::cout << "Palm attributes solver: "
<< (solver_palm_attributes.has_value() ? solver_palm_attributes.value() : "not specified")
<< std::endl;
// Print other options
std::cout << "Detection threshold: " << detection_threshold << std::endl;
}
utils::printToolkitInfo();
SFEError error{};
SFESolver detector_solver{};
DEFER(sfeSolverFree(detector_solver));
{ // STAGE 1: loading solvers
utils::printFormatted("LOADING solvers");
// Initialize palm detection solver
error = sfeSolverCreate(
SOLVER_PARAMETERS.size(), &detector_solver);
utils::checkError(error);
}
SFEImage image{};
DEFER(sfeImageFree(image));
{ // STAGE 2: Load image
utils::printFormatted("PALM DETECTION");
// Load image data from file
auto image_data = utils::readFile(image_probe);
// Decode image from data
error = sfeImageDecode(image_data.data(), image_data.size(), &image);
utils::checkError(error);
}
SFEDetection detected_palm = {};
{ // STAGE 3: Detect palm in the image
size_t detection_count = 1;
// Detect palm in the image
error = sfeDetect(detector_solver, image, detection_threshold,
&detected_palm, &detection_count);
utils::checkError(error);
if (detection_count == 0) {
std::cout << "No palm detected in the probe image." << std::endl;
return 0;
} else {
std::cout << "Found " << detection_count
<< " palm(s) in the probe image. Using the palm with highest "
"confidence."
<< std::endl;
}
}
SFEPalmLandmarks landmarks = {};
{ // STAGE 4: Extract palm landmarks
utils::printFormatted("LANDMARKS");
// Extract palm landmarks (hand position, orientation, keypoints)
error = sfePalmLandmarks(detector_solver, image, &detected_palm, &landmarks);
utils::checkError(error);
}
if (solver_palm_attributes.has_value()) { // STAGE 5: Attributes (if solver available)
SFESolver attributes_solver{};
DEFER(sfeSolverFree(attributes_solver));
// Initialize palm attributes solver
error = sfeSolverCreate(
solver_palm_attributes.value().c_str(), SOLVER_PARAMETERS.data(),
SOLVER_PARAMETERS.size(), &attributes_solver);
utils::checkError(error);
utils::printFormatted("ATTRIBUTES");
SFEPalmAttributes attributes = {};
error = sfePalmAttributes(attributes_solver, image, &landmarks,
&attributes);
utils::checkError(error);
printPalmDetectionInfo(detected_palm, landmarks);
std::cout << "Hand orientation " << attributes.hand_orientation << std::endl;
std::cout << "Hand position " << attributes.hand_position << std::endl;
std::cout << "Quality " << attributes.quality << std::endl;
} else {
printPalmDetectionInfo(detected_palm, landmarks);
std::cout << "Palm attributes solver not specified, skipping attributes analysis." << std::endl;
}
utils::printFormatted("FINISHED");
}
void printHelp()
std::string image_probe
float detection_threshold
const auto SOLVER_PARAMETERS
std::optional< std::string > solver_palm_attributes
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.
Definition sfe_core.h:102
void * SFEError
Error type used to hold optional error message.
Definition sfe_core.h:97
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.
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 sfePalmLandmarks(SFESolver solver, SFEImageView image, const SFEDetection *detection, SFEPalmLandmarks *out_landmarks)
Calculate palm landmarks from given source image and palm detection.
SFEError sfePalmAttributes(SFESolver solver, SFEImageView image, const SFEPalmLandmarks *landmarks, SFEPalmAttributes *out_attributes)
Calculate palm image quality attributes from given source image and palm detection.
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.
Definition sfe_core.h:70
float quality
Range <0, 1>. The recommended threshold for further palm processing is 0.6.
Definition sfe_palm.h:58
float hand_orientation
Definition sfe_palm.h:56
float hand_position
Definition sfe_palm.h:52
Palm landmarks (keypoints, hand position, orientation, confidence)
SFEHandPosition hand_position
Detected hand position.
SFEHandOrientation hand_orientation
Detected palm orientation.