Visual Servoing Platform  version 3.6.1 under development (2024-04-19)
tutorial-face-detector-live.cpp
1 #include <visp3/core/vpConfig.h>
3 #include <visp3/detection/vpDetectorFace.h>
4 #include <visp3/gui/vpDisplayGDI.h>
5 #include <visp3/gui/vpDisplayOpenCV.h>
6 #include <visp3/gui/vpDisplayX.h>
7 #ifdef VISP_HAVE_MODULE_SENSOR
8 #include <visp3/sensor/vpV4l2Grabber.h>
9 #endif
10 
11 #if defined(HAVE_OPENCV_VIDEOIO)
12 #include <opencv2/videoio.hpp>
13 #endif
14 
15 int main(int argc, const char *argv [])
16 {
17 #if defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_OBJDETECT)
18  try {
19  std::string opt_face_cascade_name = "./haarcascade_frontalface_alt.xml";
20  unsigned int opt_device = 0;
21  unsigned int opt_scale = 2; // Default value is 2 in the constructor. Turn
22  // it to 1 to avoid subsampling
23 
24  for (int i = 0; i < argc; i++) {
25  if (std::string(argv[i]) == "--haar")
26  opt_face_cascade_name = std::string(argv[i + 1]);
27  else if (std::string(argv[i]) == "--device")
28  opt_device = (unsigned int)atoi(argv[i + 1]);
29  else if (std::string(argv[i]) == "--scale")
30  opt_scale = (unsigned int)atoi(argv[i + 1]);
31  else if (std::string(argv[i]) == "--help") {
32  std::cout << "Usage: " << argv[0]
33  << " [--haar <haarcascade xml filename>] [--device <camera "
34  "device>] [--scale <subsampling factor>] [--help]"
35  << std::endl;
36  return EXIT_SUCCESS;
37  }
38  }
39 
40  vpImage<unsigned char> I; // for gray images
41 
43 #if defined(VISP_HAVE_V4L2)
44  vpV4l2Grabber g;
45  std::ostringstream device;
46  device << "/dev/video" << opt_device;
47  g.setDevice(device.str());
48  g.setScale(opt_scale); // Default value is 2 in the constructor. Turn it
49  // to 1 to avoid subsampling
50  g.acquire(I);
51 #elif defined(HAVE_OPENCV_VIDEOIO)
52  cv::VideoCapture cap(opt_device); // open the default camera
53 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
54  int width = (int)cap.get(cv::CAP_PROP_FRAME_WIDTH);
55  int height = (int)cap.get(cv::CAP_PROP_FRAME_HEIGHT);
56  cap.set(cv::CAP_PROP_FRAME_WIDTH, width / opt_scale);
57  cap.set(cv::CAP_PROP_FRAME_HEIGHT, height / opt_scale);
58 #else
59  int width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
60  int height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
61  cap.set(CV_CAP_PROP_FRAME_WIDTH, width / opt_scale);
62  cap.set(CV_CAP_PROP_FRAME_HEIGHT, height / opt_scale);
63 #endif
64  if (!cap.isOpened()) { // check if we succeeded
65  std::cout << "Failed to open the camera" << std::endl;
66  return EXIT_FAILURE;
67  }
68  cv::Mat frame;
69  cap >> frame; // get a new frame from camera
70  vpImageConvert::convert(frame, I);
71 #endif
73 
74 #if defined(VISP_HAVE_X11)
75  vpDisplayX d(I);
76 #elif defined(VISP_HAVE_GDI)
77  vpDisplayGDI d(I);
78 #elif defined(HAVE_OPENCV_HIGHGUI)
79  vpDisplayOpenCV d(I);
80 #endif
81  vpDisplay::setTitle(I, "ViSP viewer");
82 
83  vpDetectorFace face_detector;
84  face_detector.setCascadeClassifierFile(opt_face_cascade_name);
85 
86  while (1) {
87  double t = vpTime::measureTimeMs();
89 #if defined(VISP_HAVE_V4L2)
90  g.acquire(I);
91  bool face_found = face_detector.detect(I);
92 #else
93  cap >> frame; // get a new frame from camera
94  vpImageConvert::convert(frame, I);
95  bool face_found = face_detector.detect(frame); // We pass frame to avoid an internal image conversion
96 #endif
98 
100 
101  if (face_found) {
102  std::ostringstream text;
103  text << "Found " << face_detector.getNbObjects() << " face(s)";
104  vpDisplay::displayText(I, 10, 10, text.str(), vpColor::red);
105  for (size_t i = 0; i < face_detector.getNbObjects(); i++) {
106  vpRect bbox = face_detector.getBBox(i);
107  vpDisplay::displayRectangle(I, bbox, vpColor::green, false, 4);
108  vpDisplay::displayText(I, (int)bbox.getTop() - 10, (int)bbox.getLeft(),
109  "Message: \"" + face_detector.getMessage(i) + "\"", vpColor::red);
110  }
111  }
112  vpDisplay::displayText(I, (int)I.getHeight() - 25, 10, "Click to quit...", vpColor::red);
113  vpDisplay::flush(I);
114  if (vpDisplay::getClick(I, false)) // a click to exit
115  break;
116 
117  std::cout << "Loop time: " << vpTime::measureTimeMs() - t << " ms" << std::endl;
118  }
119  }
120  catch (const vpException &e) {
121  std::cout << e.getMessage() << std::endl;
122  }
123 #else
124  (void)argc;
125  (void)argv;
126 #endif
127 }
static const vpColor red
Definition: vpColor.h:211
static const vpColor green
Definition: vpColor.h:214
vpRect getBBox(size_t i) const
size_t getNbObjects() const
std::vector< std::string > & getMessage()
void setCascadeClassifierFile(const std::string &filename)
bool detect(const vpImage< unsigned char > &I) vp_override
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
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:128
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 emitted by ViSP classes.
Definition: vpException.h:59
const char * getMessage() const
Definition: vpException.cpp:64
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
unsigned int getHeight() const
Definition: vpImage.h:184
Defines a rectangle in the plane.
Definition: vpRect.h:76
double getLeft() const
Definition: vpRect.h:170
double getTop() const
Definition: vpRect.h:189
Class that is a wrapper over the Video4Linux2 (V4L2) driver.
void setScale(unsigned scale=vpV4l2Grabber::DEFAULT_SCALE)
void setDevice(const std::string &devname)
void acquire(vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()