Visual Servoing Platform  version 3.5.1 under development (2022-12-02)
tutorial-dnn-object-detection-live.cpp
#include <visp3/core/vpConfig.h>
#include <visp3/detection/vpDetectorDNN.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
int main(int argc, const char *argv[])
{
#if (VISP_HAVE_OPENCV_VERSION >= 0x030403) && defined(VISP_HAVE_OPENCV_DNN)
try {
int opt_device = 0;
std::string input = "";
std::string model = "opencv_face_detector_uint8.pb";
std::string config = "opencv_face_detector.pbtxt";
int inputWidth = 300, inputHeight = 300;
double meanR = 104.0, meanG = 177.0, meanB = 123.0;
double scaleFactor = 1.0;
bool swapRB = false;
float confThresh = 0.5f;
float nmsThresh = 0.4f;
std::string labelFile = "";
for (int i = 1; i < argc; i++) {
if (std::string(argv[i]) == "--device" && i + 1 < argc) {
opt_device = atoi(argv[i + 1]);
} else if (std::string(argv[i]) == "--input" && i + 1 < argc) {
input = std::string(argv[i + 1]);
} else if (std::string(argv[i]) == "--model" && i + 1 < argc) {
model = std::string(argv[i + 1]);
} else if (std::string(argv[i]) == "--config" && i + 1 < argc) {
config = std::string(argv[i + 1]);
} else if (std::string(argv[i]) == "--width" && i + 1 < argc) {
inputWidth = atoi(argv[i + 1]);
} else if (std::string(argv[i]) == "--height" && i + 1 < argc) {
inputHeight = atoi(argv[i + 1]);
} else if (std::string(argv[i]) == "--mean" && i + 3 < argc) {
meanR = atof(argv[i + 1]);
meanG = atof(argv[i + 2]);
meanB = atof(argv[i + 3]);
} else if (std::string(argv[i]) == "--scale" && i + 1 < argc) {
scaleFactor = atof(argv[i + 1]);
} else if (std::string(argv[i]) == "--swapRB") {
swapRB = true;
} else if (std::string(argv[i]) == "--confThresh" && i + 1 < argc) {
confThresh = (float)atof(argv[i + 1]);
} else if (std::string(argv[i]) == "--nmsThresh" && i + 1 < argc) {
nmsThresh = (float)atof(argv[i + 1]);
} else if (std::string(argv[i]) == "--labels" && i + 1 < argc) {
labelFile = std::string(argv[i + 1]);
} else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
std::cout << argv[0]
<< " --device <camera device number> --input <path to image or video>"
" (camera is used if input is empty) --model <path to net trained weights>"
" --config <path to net config file>"
" --width <blob width> --height <blob height>"
" -- mean <meanR meanG meanB> --scale <scale factor>"
" --swapRB --confThresh <confidence threshold>"
" --nmsThresh <NMS threshold> --labels <path to label file>"
<< std::endl;
return EXIT_SUCCESS;
}
}
std::cout << "Model: " << model << std::endl;
std::cout << "Config: " << config << std::endl;
std::cout << "Width: " << inputWidth << std::endl;
std::cout << "Height: " << inputHeight << std::endl;
std::cout << "Mean: " << meanR << ", " << meanG << ", " << meanB << std::endl;
std::cout << "Scale: " << scaleFactor << std::endl;
std::cout << "Swap RB? " << swapRB << std::endl;
std::cout << "Confidence threshold: " << confThresh << std::endl;
std::cout << "NMS threshold: " << nmsThresh << std::endl;
cv::VideoCapture capture;
if (input.empty()) {
capture.open(opt_device);
} else {
capture.open(input);
}
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GDI)
#elif defined(VISP_HAVE_OPENCV)
#endif
dnn.readNet(model, config);
dnn.setInputSize(inputWidth, inputHeight);
dnn.setMean(meanR, meanG, meanB);
dnn.setScaleFactor(scaleFactor);
dnn.setSwapRB(swapRB);
dnn.setConfidenceThreshold(confThresh);
dnn.setNMSThreshold(nmsThresh);
std::vector<std::string> labels;
if (!labelFile.empty()) {
std::ifstream f_label(labelFile);
std::string line;
while (std::getline(f_label, line)) {
labels.push_back(line);
}
}
cv::Mat frame;
while (true) {
capture >> frame;
if (frame.empty())
break;
if (I.getSize() == 0) {
d.init(I);
vpDisplay::setTitle(I, "DNN object detection");
} else {
}
double t = vpTime::measureTimeMs();
std::vector<vpRect> boundingBoxes;
dnn.detect(I, boundingBoxes);
std::vector<int> classIds = dnn.getDetectionClassIds();
std::vector<float> confidences = dnn.getDetectionConfidence();
for (size_t i = 0; i < boundingBoxes.size(); i++) {
vpDisplay::displayRectangle(I, boundingBoxes[i], vpColor::red, false, 2);
std::ostringstream oss;
if (labels.empty())
oss << "class: " << classIds[i];
else
oss << labels[classIds[i]];
oss << " - conf: " << confidences[i];
vpDisplay::displayText(I, (int)boundingBoxes[i].getTop() - 10, (int)boundingBoxes[i].getLeft() + 10, oss.str(),
}
std::ostringstream oss;
oss << "Detection time: " << t << " ms";
vpDisplay::displayText(I, 20, 20, oss.str(), vpColor::red);
if (vpDisplay::getClick(I, false))
break;
}
} catch (const vpException &e) {
std::cout << e.what() << std::endl;
}
#else
(void)argc;
(void)argv;
#endif
return EXIT_SUCCESS;
}
static const vpColor red
Definition: vpColor.h:217
std::vector< float > getDetectionConfidence(bool afterNMS=true) const
void setMean(double meanR, double meanG, double meanB)
void setInputSize(int width, int height)
void setScaleFactor(double scaleFactor)
void readNet(const std::string &model, const std::string &config="", const std::string &framework="")
void setNMSThreshold(float nmsThreshold)
void setConfidenceThreshold(float confThreshold)
void setSwapRB(bool swapRB)
std::vector< int > getDetectionClassIds(bool afterNMS=true) const
virtual bool detect(const vpImage< unsigned char > &I)
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:135
void init(vpImage< unsigned char > &I, int win_x=-1, int win_y=-1, const std::string &win_title="")
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void setTitle(const vpImage< unsigned char > &I, const std::string &windowtitle)
static void flush(const vpImage< unsigned char > &I)
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emited by ViSP classes.
Definition: vpException.h:72
const char * what() const
Definition: vpException.cpp:99
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
unsigned int getSize() const
Definition: vpImage.h:227
VISP_EXPORT double measureTimeMs()