Companion must only be configured by its Companion Configuration class.
// Creates an empty Companion configuration class
std::unique_ptr<COMPANION> companion = std::make_unique<COMPANION>();
This configuration class specifies which image processing implementation should be used. The following components must be initialized:
The following object recognition scenario describes all configuration steps of the Companion framework. The goal is to recognize two posters in a video source.
Poster A | Poster B |
---|---|
Simple set a result and error handler to a Companion configuration to obtain results and errors by a running Companion execution.
companion->ResultCallback(resultHandler);
companion->ErrorCallback(errorHandler);
To obtain results from Companion you have to implement a result and an error handler. The result handler has to implement the following function type:
void ResultHandler(CALLBACK_RESULT results, cv::Mat source);
In this example (Feature Matching) the results represent all recognized objects in a single image frame.
void resultHandler(CALLBACK_RESULT results, cv::Mat source)
{
PTR_DRAW_FRAME frame;
PTR_RESULT result;
for (size_t i = 0; i < results.size(); i++)
{
// Mark the detected or recognized object
result = results.at(i);
result->Drawable()->Draw(source);
// Draw the id of the detected or recognized object
frame = std::dynamic_pointer_cast<DRAW_FRAME>(result->Drawable());
if (frame != nullptr)
{
cv::putText(source,
result->Description(),
frame->TopRight(),
cv::FONT_HERSHEY_DUPLEX,
2.0,
frame->Color(),
frame->Thickness()
);
}
}
cv::imshow("Companion", source);
cv::waitKey(1);
source.release();
results.clear();
}
If an error occurs during the image processing, Companion will throw a specific Companion::Error::Code. A corresponding error message can be obtained with the help of an error handler like this:
void errorHandler(Companion::Error::Code code)
{
// Obtain detailed error message from code
std::cout << Companion::Error::Error(code) << std::endl;
}
The Companion configuration expects an image processing object as input. All supported image processing methods are derived from the ImageProcessing abstract class. For example, a MatchRecognition object (which uses OpenCV Feature Matching algorithms) can be configured as follows:
// -------------- BRISK CPU FM --------------
int type = cv::DescriptorMatcher::BRUTEFORCE_HAMMINGLUT;
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(type);
cv::Ptr<cv::BRISK> feature = cv::BRISK::create(60);
PTR_MATCHING_RECOGNITION matching = std::make_shared<FEATURE_MATCHING>(feature, feature, matcher, type, 10, 10, true);
PTR_MATCH_RECOGNITION recognition = std::make_shared<MATCH_RECOGNITION>(matching, Companion::SCALING::SCALE_640x360);
Different image processing methods may have different search model types. For example, to use the Feature Matching algorithm a FeatureMatchingModel object has to be created for each search model.
for (int i = 0; i < images.size(); i++)
{
PTR_MODEL_FEATURE_MATCHING model = std::make_shared<MODEL_FEATURE_MATCHING>();
model->ID(i);
model->Image(cv::imread(images[i], cv::IMREAD_GRAYSCALE));
if (!recognition->AddModel(model))
{
std::cout << "Model not added";
}
}
After all configuration steps are performed, you can run Companion in a try/catch block. If Companion is miss-configured a Companion Error Code will be thrown.
try
{
companion->Run();
}
catch (Companion::Error::Code errorCode)
{
errorHandler(errorCode);
}