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 | 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 | MStr = std::map< std::string, std::string > |
Map of strings where both the key and the value are std::string . More... | |
using | VStr = std::vector< std::string > |
Vector of text strings. Typically used to store the class names. More... | |
using | VColours = std::vector< cv::Scalar > |
Vector of colours to use by DarkHelp::NN::annotate(). More... | |
using | VInt = std::vector< int > |
Vector of int used with OpenCV. More... | |
using | VFloat = std::vector< float > |
Vector of float 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 | MClassProbabilities = std::map< int, float > |
Map of a class ID to a probability that this object belongs to that class. More... | |
using | PredictionResults = std::vector< PredictionResult > |
A vector of predictions for the image analyzed by DarkHelp::NN::predict(). 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::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 DarkHelp::PositionTracker &tracker) |
Convenience function to stream the entire object tracker as 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... | |
std::string | version () |
Get a version string for the DarkHelp library. E.g., could be 1.0.0-123 . 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... | |
VColours | get_default_annotation_colours () |
Obtain a vector of at least 25 different bright colours that may be used to annotate images. 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... | |
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 | 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... | |
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 | 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... | |
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... | |
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... | |
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... | |
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... | |
PredictionResults | yolo_load_annotations (const cv::Size &image_size, const std::string &filename) |
Load the YOLO annotations from file. More... | |
std::string | yolo_save_annotations (const std::string &filename, const PredictionResults &annotations) |
Save the given annotations to the .txt file. 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... | |
void | pixelate_rectangle (const cv::Mat &src, cv::Mat &dst, const cv::Rect &r, const int size=15) |
Pixelate the given rectangle. More... | |
void | toggle_output_redirection () |
Toggle STDOUT and STDERR output redirection. 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::MStr = typedef std::map<std::string, std::string> |
Map of strings where both the key and the value are std::string
.
using DarkHelp::VStr = typedef std::vector<std::string> |
Vector of text strings. Typically used to store the class names.
using DarkHelp::VColours = typedef std::vector<cv::Scalar> |
Vector of colours to use by DarkHelp::NN::annotate().
using DarkHelp::VInt = typedef std::vector<int> |
Vector of int
used with OpenCV.
using DarkHelp::VFloat = typedef std::vector<float> |
Vector of float
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::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::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.
|
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
.
kDarknet
will result in the execution of experimental code.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::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.
std::ostream & DarkHelp::operator<< | ( | std::ostream & | os, |
const DarkHelp::PositionTracker & | tracker | ||
) |
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.
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. std::string DarkHelp::version | ( | ) |
Get a version string for the DarkHelp library. E.g., could be 1.0.0-123
.
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"
.
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 |
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 |
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 |
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.
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.
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.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.
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.
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().
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?) |
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) |
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 |
void DarkHelp::pixelate_rectangles | ( | const cv::Mat & | src, |
cv::Mat & | dst, | ||
const PredictionResults & | prediction_results, | ||
const int | size = 15 |
||
) |
Pixelate all of the predictions.
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.
void DarkHelp::pixelate_rectangles | ( | const cv::Mat & | src, |
cv::Mat & | dst, | ||
const VRect & | rects, | ||
const int | size = 15 |
||
) |
Pixelate all of the rectangles.
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 | ![]() |
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.