The DarkHelp namespace contains (almost) everything in the DarkHelp library. More...
Classes | |
class | Config |
All of DarkHelp's configuration is stored within an instance of this class. More... | |
class | DHThreads |
This class allows you to easily run multiple identical copies of a neural network to process many files at once. More... | |
class | NN |
Instantiate one of these objects by giving it the name of the .cfg and .weights file, then call DarkHelp::NN::predict() as often as necessary to determine what the images contain. More... | |
class | PositionTracker |
This class attempts to do very simple object tracking based on the position of the object. More... | |
struct | PredictionResult |
Structure used to store interesting information on predictions. More... | |
Typedefs | |
using | MClassProbabilities = std::map< int, float > |
Map of a class ID to a probability that this object belongs to that class. More... | |
using | MStr = std::map< std::string, std::string > |
Map of strings where both the key and the value are std::string . More... | |
using | PredictionResults = std::vector< PredictionResult > |
A vector of predictions for the image analyzed by DarkHelp::NN::predict(). More... | |
using | VColours = std::vector< cv::Scalar > |
Vector of colours to use by DarkHelp::NN::annotate(). More... | |
using | VFloat = std::vector< float > |
Vector of float used with OpenCV. More... | |
using | VInt = std::vector< int > |
Vector of int used with OpenCV. More... | |
using | VRect = std::vector< cv::Rect > |
Vector of OpenCV rectangles used with OpenCV. More... | |
using | VRect2d = std::vector< cv::Rect2d > |
Similar to DarkHelp::VRect, but the rectangle uses double instead of int . More... | |
using | VStr = std::vector< std::string > |
Vector of text strings. Typically used to store the class names. More... | |
Enumerations | |
enum | EDriver { EDriver::kInvalid = 0, EDriver::kMin = 1, EDriver::kDarknet = kMin, EDriver::kOpenCV, EDriver::kOpenCVCPU, EDriver::kMax = kOpenCVCPU } |
DarkHelp can utilise either libdarknet.so or OpenCV's DNN module to load the neural network and run inference. More... | |
enum | ESort { ESort::kUnsorted = 0, ESort::kAscending, ESort::kDescending, ESort::kPageOrder } |
Functions | |
std::filesystem::path | combine (const std::string &key, const std::filesystem::path &cfg_filename, const std::filesystem::path &names_filename, const std::filesystem::path &weights_filename) |
Combine together the 3 files that make up a neural network, and obfuscate them using the given key phrase. More... | |
std::string | duration_string (const std::chrono::high_resolution_clock::duration duration) |
Format a duration as a text string which is typically added to images or video frames during annotation. More... | |
size_t | edit_cfg_file (const std::string &cfg_filename, MStr m) |
This is used to insert lines into the [net] section of the configuration file. More... | |
void | extract (const std::string &key, const std::filesystem::path &bundle, std::filesystem::path &cfg_filename, std::filesystem::path &names_filename, std::filesystem::path &weights_filename) |
Extract the 3 files that make up a neural network. More... | |
cv::Mat | fast_resize_ignore_aspect_ratio (const cv::Mat &mat, const cv::Size &desired_size) |
Resize the given image as quickly as possible to the given dimensions. More... | |
void | fix_out_of_bound_normalized_rect (float &cx, float &cy, float &w, float &h) |
Automatically called by DarkHelp::NN::predict_internal() when DarkHelp::Config::fix_out_of_bound_values has been set. More... | |
VColours | get_default_annotation_colours () |
Obtain a vector of at least 25 different bright colours that may be used to annotate images. More... | |
std::ostream & | operator<< (std::ostream &os, const DarkHelp::PositionTracker &tracker) |
Convenience function to stream the entire object tracker as text. More... | |
std::ostream & | operator<< (std::ostream &os, const DarkHelp::PositionTracker::Obj &obj) |
Convenience function to stream a single tracked object as a line of text. More... | |
std::ostream & | operator<< (std::ostream &os, const PredictionResult &pred) |
Convenience function to stream a single result as a "readable" line of text. More... | |
std::ostream & | operator<< (std::ostream &os, const PredictionResults &results) |
Convenience function to stream an entire vector of results as readable text. More... | |
void | pixelate_rectangle (const cv::Mat &src, cv::Mat &dst, const cv::Rect &r, const int size=15) |
Pixelate the given rectangle. More... | |
void | pixelate_rectangles (const cv::Mat &src, cv::Mat &dst, const PredictionResults &prediction_results, const int size=15) |
Pixelate all of the predictions. More... | |
void | pixelate_rectangles (const cv::Mat &src, cv::Mat &dst, const PredictionResults &prediction_results, const std::set< int > &class_filter, const int size=15) |
Pixelate only the predictions where the class ID matches a value in the class filter. More... | |
void | pixelate_rectangles (const cv::Mat &src, cv::Mat &dst, const VRect &rects, const int size=15) |
Pixelate all of the rectangles. More... | |
cv::Mat | resize_keeping_aspect_ratio (cv::Mat mat, const cv::Size &desired_size) |
Convenience function to resize an image yet retain the exact original aspect ratio. More... | |
cv::Mat | slow_resize_ignore_aspect_ratio (const cv::Mat &mat, const cv::Size &desired_size) |
Similar to DarkHelp::fast_resize_ignore_aspect_ratio() but uses OpenCV algorithms that result in better quality images at a cost of slower speed. More... | |
void | toggle_output_redirection () |
Toggle STDOUT and STDERR output redirection. More... | |
MStr | verify_cfg_and_weights (std::string &cfg_filename, std::string &weights_filename, std::string &names_filename) |
Look at the names and/or the contents of all 3 files and swap the filenames around if necessary so the .cfg, .weights, and .names are assigned where they should be. More... | |
std::string | version () |
Get a version string for the DarkHelp library. E.g., could be 1.0.0-123 . More... | |
bool | yolo_annotations_file_exists (const std::string &image_filename) |
Check to see if the given image has a corresponding .txt file for YOLO annotations. More... | |
std::string | yolo_annotations_filename (const std::string &image_filename) |
Given an image filename, get the corresponding filename where the YOLO annotations should be saved. More... | |
PredictionResults | yolo_load_annotations (const cv::Size &image_size, const std::string &filename) |
Load the YOLO annotations from file. More... | |
cv::Mat | yolo_load_image_and_annotations (const std::string &image_filename, PredictionResults &annotations) |
Load the given image and read in the corresponding YOLO annotations from the .txt file. More... | |
std::string | yolo_save_annotations (const std::string &filename, const PredictionResults &annotations) |
Save the given annotations to the .txt file. More... | |
The DarkHelp namespace contains (almost) everything in the DarkHelp library.
Prior to version 1.4, DarkHelp
was the name of a class. But in October/November 2021, a large code re-organization took place, and the previous class definition was split into multiple classes across several files. This makes things easier to manage and was needed to support other projects like DarkHelpFPS.
Appologies to everyone who has code that relied on the previous DarkHelp
API. The old Darkhelp
class has been renamed to DarkHelp::NN, and the settings that used to be in DarkHelp
have been moved to DarkHelp::NN::config.
using DarkHelp::MClassProbabilities = typedef std::map<int, float> |
Map of a class ID to a probability that this object belongs to that class.
The key is the zero-based index of the class, while the value is the probability that the object belongs to that class.
using DarkHelp::MStr = typedef std::map<std::string, std::string> |
Map of strings where both the key and the value are std::string
.
using DarkHelp::PredictionResults = typedef std::vector<PredictionResult> |
A vector of predictions for the image analyzed by DarkHelp::NN::predict().
Each DarkHelp::PredictionResult entry in the vector represents a different object in the image.
using DarkHelp::VColours = typedef std::vector<cv::Scalar> |
Vector of colours to use by DarkHelp::NN::annotate().
using DarkHelp::VFloat = typedef std::vector<float> |
Vector of float
used with OpenCV.
using DarkHelp::VInt = typedef std::vector<int> |
Vector of int
used with OpenCV.
using DarkHelp::VRect = typedef std::vector<cv::Rect> |
Vector of OpenCV rectangles used with OpenCV.
using DarkHelp::VRect2d = typedef std::vector<cv::Rect2d> |
Similar to DarkHelp::VRect, but the rectangle uses double
instead of int
.
using DarkHelp::VStr = typedef std::vector<std::string> |
Vector of text strings. Typically used to store the class names.
|
strong |
DarkHelp can utilise either libdarknet.so
or OpenCV's DNN module to load the neural network and run inference.
OpenCV is much faster, but support for it is relatively new in DarkHelp and support for newer models like YOLOv4 requires very recent versions of OpenCV. The default is kDarknet
.
If using kOpenCV
or kOpenCVCPU
you can customize the backend and target after DarkHelp::init() is called. For example:
|
strong |
Enumerator | |
---|---|
kUnsorted | Do not sort predictions. |
kAscending | Sort predictions using DarkHelp::PredictionResult::best_probability in ascending order (low values first, high values last). |
kDescending | Sort predictions using DarkHelp::PredictionResult::best_probability in descending order (high values first, low values last). |
kPageOrder | Sort predictions based loosely on where they appear within the image. From top-to-bottom, and left-to-right. |
std::filesystem::path DarkHelp::combine | ( | const std::string & | key, |
const std::filesystem::path & | cfg_filename, | ||
const std::filesystem::path & | names_filename, | ||
const std::filesystem::path & | weights_filename | ||
) |
Combine together the 3 files that make up a neural network, and obfuscate them using the given key phrase.
Normally, this is done using the DarkHelpCombine
command line tool.
Command-line example:
Once you have a .dh bundle file (the output of running
DarkHelpCombine
) you can load it into DarkHelp using either the DarkHelp::NN::NN() or DarkHelp::DHThreads::DHThreads() constructors that takes a bundle filename and the key phrase.
References verify_cfg_and_weights().
Referenced by main().
std::string DarkHelp::duration_string | ( | const std::chrono::high_resolution_clock::duration | duration | ) |
Format a duration as a text string which is typically added to images or video frames during annotation.
For example, this might return "912 microseconds"
or "375 milliseconds"
.
Referenced by DarkHelp::NN::annotate(), and DarkHelp::NN::duration_string().
size_t DarkHelp::edit_cfg_file | ( | const std::string & | cfg_filename, |
DarkHelp::MStr | m | ||
) |
This is used to insert lines into the [net] section of the configuration file.
Pass in a map of key-value pairs, and if the key exists it will be modified. If the key does not exist, then it will be added to the bottom of the [net] section.
For example, this is used by DarkHelp::NN::init() when DarkHelp::Config::modify_batch_and_subdivisions is enabled.
std::invalid_argument | if the cfg file does not exist or cannot be opened |
std::runtime_error | if a valid start and end to the [net] section wasn't found in the .cfg file |
std::runtime_error | if we cannot write a new .cfg file |
std::runtime_error | if we cannot rename the .cfg file |
Referenced by DarkHelp::DHThreads::init(), and DarkHelp::NN::init().
void DarkHelp::extract | ( | const std::string & | key, |
const std::filesystem::path & | bundle, | ||
std::filesystem::path & | cfg_filename, | ||
std::filesystem::path & | names_filename, | ||
std::filesystem::path & | weights_filename | ||
) |
Extract the 3 files that make up a neural network.
Referenced by DarkHelp::DHThreads::init(), and DarkHelp::NN::init().
cv::Mat DarkHelp::fast_resize_ignore_aspect_ratio | ( | const cv::Mat & | mat, |
const cv::Size & | desired_size | ||
) |
Resize the given image as quickly as possible to the given dimensions.
This will sacrifice quality for speed. If OpenCV has been compiled with support for CUDA, then this will utilise the GPU to do the resizing.
cv::resize()
. Probably would be of bigger impact if the image resizing was done on a different thread, and then fed to DarkHelp for inference so the image resize and inference can happen in parallel.Referenced by DarkHelp::NN::predict_internal_darknet(), and DarkHelp::NN::predict_internal_opencv().
void DarkHelp::fix_out_of_bound_normalized_rect | ( | float & | cx, |
float & | cy, | ||
float & | w, | ||
float & | h | ||
) |
Automatically called by DarkHelp::NN::predict_internal() when DarkHelp::Config::fix_out_of_bound_values has been set.
Referenced by DarkHelp::NN::predict_internal_darknet(), DarkHelp::NN::predict_internal_opencv(), and yolo_load_annotations().
DarkHelp::VColours DarkHelp::get_default_annotation_colours | ( | ) |
Obtain a vector of at least 25 different bright colours that may be used to annotate images.
OpenCV uses BGR, not RGB. For example:
"{0, 0, 255}"
is pure red "{255, 0, 0}"
is pure blueThe colours returned by this function are intended to be used by OpenCV, and thus are in BGR format.
Default colours returned by this method are:
Index | RGB Hex | Name |
---|---|---|
0 | FF355E | Radical Red |
1 | 299617 | Slimy Green |
2 | FFCC33 | Sunglow |
3 | AF6E4D | Brown Sugar |
4 | FF00FF | Pure magenta |
5 | 50BFE6 | Blizzard Blue |
6 | CCFF00 | Electric Lime |
7 | 00FFFF | Pure cyan |
8 | 8D4E85 | Razzmic Berry |
9 | FF48CC | Purple Pizzazz |
10 | 00FF00 | Pure green |
11 | FFFF00 | Pure yellow |
12 | 5DADEC | Blue Jeans |
13 | FF6EFF | Shocking Pink |
14 | AAF0D1 | Magic Mint |
15 | FFC000 | Orange |
16 | 9C51B6 | Purple Plum |
17 | FF9933 | Neon Carrot |
18 | 66FF66 | Screamin' Green |
19 | FF0000 | Pure red |
20 | 4B0082 | Indigo |
21 | FF6037 | Outrageous Orange |
22 | FFFF66 | Laser Lemon |
23 | FD5B78 | Wild Watermelon |
24 | 0000FF | Pure blue |
Referenced by DarkHelp::NN::annotate(), and DarkHelp::Config::reset().
std::ostream & DarkHelp::operator<< | ( | std::ostream & | os, |
const DarkHelp::PositionTracker & | tracker | ||
) |
Convenience function to stream the entire object tracker as text.
Mostly intended for debug or logging purposes.
Example:
References DarkHelp::PositionTracker::most_recent_frame_id, DarkHelp::PositionTracker::most_recent_object_id, and DarkHelp::PositionTracker::objects.
std::ostream & DarkHelp::operator<< | ( | std::ostream & | os, |
const DarkHelp::PositionTracker::Obj & | obj | ||
) |
Convenience function to stream a single tracked object as a line of text.
Mostly intended for debug or logging purposes.
References DarkHelp::PositionTracker::Obj::center(), DarkHelp::PositionTracker::Obj::fids_and_rects, DarkHelp::PositionTracker::Obj::first_seen_frame_id(), DarkHelp::PositionTracker::Obj::last_seen_frame_id(), DarkHelp::PositionTracker::Obj::oid, and DarkHelp::PositionTracker::Obj::size().
Referenced by operator<<().
std::ostream & DarkHelp::operator<< | ( | std::ostream & | os, |
const PredictionResult & | pred | ||
) |
Convenience function to stream a single result as a "readable" line of text.
Mostly intended for debug or logging purposes.
References DarkHelp::PredictionResult::all_probabilities, DarkHelp::PredictionResult::best_class, DarkHelp::PredictionResult::best_probability, DarkHelp::PredictionResult::name, DarkHelp::PredictionResult::object_id, DarkHelp::PredictionResult::rect, and DarkHelp::PredictionResult::tile.
std::ostream & DarkHelp::operator<< | ( | std::ostream & | os, |
const PredictionResults & | results | ||
) |
Convenience function to stream an entire vector of results as readable text.
Mostly intended for debug or logging purposes.
For example:
This would generate text similar to this:
Where:
"1/12"
is the number of predictions found. "Barcode 94%"
is the class name and the probability if DarkHelp::Config::names_include_percentage is enabled. "#43"
is the zero-based class index. "prob=0.939646"
is the probabilty that it is class #43. (Multiply by 100 to get percentage.) "x=..."
are the X, Y, width, and height of the rectangle that was identified. "entries=1"
means that only 1 class was matched. If there is more than 1 possible class, then the class index and probability for each class will be shown. References operator<<().
void DarkHelp::pixelate_rectangle | ( | const cv::Mat & | src, |
cv::Mat & | dst, | ||
const cv::Rect & | r, | ||
const int | size = 15 |
||
) |
Pixelate the given rectangle.
This will copy the src
image to dst
prior to pixelating if the two images are not the same size.
The size
determines the width and height of the cells that will be used to pixelate the rectangle. If size
is less than 5
, no pixelation will take place.
Setting | Image |
---|---|
annotation_pixelate_enabled=false | |
annotation_pixelate_enabled=true annotation_pixelate_size=5 | |
annotation_pixelate_enabled=true annotation_pixelate_size=15 | |
annotation_pixelate_enabled=true annotation_pixelate_size=25 |
Referenced by pixelate_rectangles().
void DarkHelp::pixelate_rectangles | ( | const cv::Mat & | src, |
cv::Mat & | dst, | ||
const PredictionResults & | prediction_results, | ||
const int | size = 15 |
||
) |
Pixelate all of the predictions.
References pixelate_rectangle().
Referenced by DarkHelp::NN::annotate().
void DarkHelp::pixelate_rectangles | ( | const cv::Mat & | src, |
cv::Mat & | dst, | ||
const PredictionResults & | prediction_results, | ||
const std::set< int > & | class_filter, | ||
const int | size = 15 |
||
) |
Pixelate only the predictions where the class ID matches a value in the class filter.
If the class filter is empty then this will pixelate all predictions.
References pixelate_rectangle().
void DarkHelp::pixelate_rectangles | ( | const cv::Mat & | src, |
cv::Mat & | dst, | ||
const VRect & | rects, | ||
const int | size = 15 |
||
) |
Pixelate all of the rectangles.
References pixelate_rectangle().
cv::Mat DarkHelp::resize_keeping_aspect_ratio | ( | cv::Mat | mat, |
const cv::Size & | desired_size | ||
) |
Convenience function to resize an image yet retain the exact original aspect ratio.
Performs no resizing if the image is already the desired size. Depending on the size of the original image and the desired size, a "best" size will be chosen that does not exceed the specified size. No letterboxing will be performed.
For example, if the image is 640x480, and the specified size is 400x400, the image returned will be 400x300 which maintains the original 1.333 aspect ratio.
References slow_resize_ignore_aspect_ratio().
Referenced by process_image(), and process_video().
cv::Mat DarkHelp::slow_resize_ignore_aspect_ratio | ( | const cv::Mat & | mat, |
const cv::Size & | desired_size | ||
) |
Similar to DarkHelp::fast_resize_ignore_aspect_ratio() but uses OpenCV algorithms that result in better quality images at a cost of slower speed.
Referenced by DarkHelp::NN::predict_internal_darknet(), DarkHelp::NN::predict_internal_opencv(), and resize_keeping_aspect_ratio().
void DarkHelp::toggle_output_redirection | ( | ) |
Toggle STDOUT and STDERR output redirection.
The first time this is called, both STDOUT
and STDERR
will be redirected to /dev/null
(on Linux) or NUL:
(on Windows). Then when called again, both STDOUT
and STDERR
should be restored to their original location. This is used to temporarily redirect the flood of output from Darknet while it loads the neural network. This may be called multiple times as necessary to toggle the state of redirection.
Referenced by DarkHelp::NN::init(), and ToggleOutputRedirection().
DarkHelp::MStr DarkHelp::verify_cfg_and_weights | ( | std::string & | cfg_filename, |
std::string & | weights_filename, | ||
std::string & | names_filename | ||
) |
Look at the names and/or the contents of all 3 files and swap the filenames around if necessary so the .cfg,
.weights, and
.names are assigned where they should be.
This is necessary because darknet tends to segfault if it is given the wrong filename. (For example, if it mistakenly tries to parse the .weights file as a
.cfg file.) This function does a bit of sanity checking, determines which file is which, and also returns a map of debug information related to each file.
On input, it doesn't matter which file goes into which parameter. Simply pass in the filenames in any order.
On output, the .cfg,
.weights, and
.names will be set correctly. If needed for display purposes, some additional information is also passed back using the
MStr
string map, but most callers should ignore this output.
std::invalid_argument | if at least 2 unique filenames have not been provided |
std::runtime_error | if the size of the files cannot be determined (one or more file does not exist?) |
std::invalid_argument | if the cfg file doesn't exist |
std::invalid_argument | if the cfg file doesn't contain "[net]" near the top of the file |
std::invalid_argument | if the configuration file does not have a line that says "classes=..." |
std::invalid_argument | if the weights file doesn't exist |
std::invalid_argument | if weights file has an invalid version number (or weights file is from an extremely old version of darknet?) |
std::invalid_argument | if there is a blank line in the .names file. |
std::runtime_error | if the number of lines in the names file doesn't match the number of classes in the configuration file |
Referenced by combine(), DarkHelp::Config::Config(), DarkHelp::DHThreads::init(), DarkHelp::NN::init(), and init().
std::string DarkHelp::version | ( | ) |
Get a version string for the DarkHelp library. E.g., could be 1.0.0-123
.
Referenced by configure(), and DarkHelpVersion().
bool DarkHelp::yolo_annotations_file_exists | ( | const std::string & | image_filename | ) |
Check to see if the given image has a corresponding .txt file for YOLO annotations.
This does not check the contents of the file, it only checks to see if the file exists. The annotation file is determined by calling yolo_annotations_filename().
References yolo_annotations_filename().
Referenced by yolo_load_annotations().
std::string DarkHelp::yolo_annotations_filename | ( | const std::string & | image_filename | ) |
Given an image filename, get the corresponding filename where the YOLO annotations should be saved.
This will be the same as the image filename but with a .txt file extension. If the filename provided already ends in
.txt, then the original filename will be returned.
Referenced by yolo_annotations_file_exists(), yolo_load_annotations(), and yolo_save_annotations().
DarkHelp::PredictionResults DarkHelp::yolo_load_annotations | ( | const cv::Size & | image_size, |
const std::string & | filename | ||
) |
Load the YOLO annotations from file.
[in] | image_size | Since YOLO annotations are normalized, the image dimensions must be provided for the cv::Rect object to be populated with the correct coordinates. |
[out] | filename | Can be either the image filename, or the annotations filename. This is then used in a call to yolo_annotations_filename() to find the actual annotations filename. |
Each line of a YOLO-format annotation is composed of 5 space-delimited fields:
std::invalid_argument | if the annotation file does not exist |
std::invalid_argument | if the image dimensions appear to be invalid (both width and height should be greater than zero) |
References DarkHelp::PredictionResult::all_probabilities, DarkHelp::PredictionResult::best_class, DarkHelp::PredictionResult::best_probability, fix_out_of_bound_normalized_rect(), DarkHelp::PredictionResult::name, DarkHelp::PredictionResult::original_point, DarkHelp::PredictionResult::original_size, DarkHelp::PredictionResult::rect, DarkHelp::PredictionResult::tile, yolo_annotations_file_exists(), and yolo_annotations_filename().
Referenced by yolo_load_image_and_annotations().
cv::Mat DarkHelp::yolo_load_image_and_annotations | ( | const std::string & | image_filename, |
DarkHelp::PredictionResults & | annotations | ||
) |
Load the given image and read in the corresponding YOLO annotations from the .txt file.
Both the image and the .txt file must exist.
Each line of a YOLO-format annotation is composed of 5 space-delimited fields:
std::invalid_argument | if the image cannot be read (not an image file, or invalid filename?) |
References yolo_load_annotations().
std::string DarkHelp::yolo_save_annotations | ( | const std::string & | filename, |
const PredictionResults & | annotations | ||
) |
Save the given annotations to the .txt file.
The filename can be either the image or the .txt file, and will be used to call yolo_annotations_filename().
Each line of a YOLO-format annotation is composed of 5 space-delimited fields, and is intended to be used by Darknet or Darknet-compatible software.
std::invalid_argument | if the annotation file fails to open |
References yolo_annotations_filename().