People head detection code and performance of Opencv 4 compared to opencv 3.2

Opencv 4.0 is released, people head detection compared to opencv 3.2

I am working with opencv for almost a 6 years. It is 3.5 years since the 3.0. The journey driven by DNN, new ideas, algorithms and optimization is breathtaking.  Thanks to all contributors. Here is my point of view to opencv 4.0.  The video comparison of opencv 4 and 3.2 with head and shoulders detection performance at the end of the article with sample code. 

opencv 4 performance detection
opencv 4 - opencv 3.2 performace comparison

Opencv 4.0 main changes

C++11 is one of the main changes that will programmer realize at the first. This brings a lot of advantages to write safer and stable code. Smart pointers in C++11 and many features of the standard library helps to write code safer and with better performance. The reinventing the wheel is a weakness of all programmers. Better is know what is already available in various libraries and use it. The 30 years of sorting, algorithm and memory handling do not wait for application programmers reinvent.  

Opencv 4.0 C API removed

It is mentioned removed C API from 1.x. I need to dive deeper into this. I used this API in FFmpeg combination with opencv long long time ago. Sometimes, I like old C more than C++. I get the point. I can take it. The maintain the C API there is no point.

OPENCV 4.0 XML YAML and JSON loading and storing

The configuration parsing of DNN and various other algorithm is key for automation and basically most of the annoying parts of the program. If you ever write your own parser for CSV, XML or JSON you know what is the most boring experience in programming :).

Opencv 4.0 G-API

New module G-API  is an engine for very efficient graph-based image processing pipelines. This looks interesting and can speed up performance and as well development. An example can be to prepare image into some specific stage.  Basically, G api is input-output pipeline and between input and output, you can perform very fast transformation of your image. It is as well very efficient from the point of memory management and access. Following example define pipeline from an input image to resized image to grayscale image,. If you want to use this pipeline in the code just write cv::GComputation ac(in, out);. The all the pipeline from input and output will be performed.

cv::GMat in;
cv::GMat vga = cv::gapi::resize(in, cv::Size(), 0.5, 0.5);
cv::GMat out = cv::gapi::BGR2Gray(vga);
cv::GComputation ac(in, out);

This can be very cool features. I will learn more about and prepare some of my thoughts about G-API.

Opencv 4.0 DNN module

Dnn module now includes experimental Vulkan backend. Vulkan is cross-platform 3D graphics computation API. New alternative against OpenGL and Direct3D. This can speed up processing of some layers in DNN as in case of 3D graphics. The representations and models are pretty much the same from the internal point of view. 

Opencv 4 vs 3.2 Opencv performance 

Both are optimized as much as possible for I7 HW without GPU. The development does not focus exactly on LBP cascade detectMultiscale. This both opencv tasks performing really similar on this concrete problem.


Opencv 4 cmake build configuration

This is just my example of cmake configuration. I am not using any special magic right now to build opencv 4.0.0.
General configuration for OpenCV 4.0.0 =====================================
Version control: unknown
Timestamp: 2018-11-25T10:16:09Z
Host: Windows 10.0.17134 AMD64
CMake: 3.13.0-rc2
CMake generator: Visual Studio 15 2017 Win64
CMake build tool: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/MSBuild/15.0/Bin/MSBuild.exe
MSVC: 1915
CPU/HW features:
Baseline: SSE SSE2 SSE3
requested: SSE3
Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2
requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
SSE4_1 (7 files): + SSSE3 SSE4_1
SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2
FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
AVX (5 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
AVX2 (13 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
FFMPEG: YES (prebuilt binaries)
avcodec: YES (ver 58.35.100)
avformat: YES (ver 58.20.100)
avutil: YES (ver 56.22.100)
swscale: YES (ver 5.3.100)
avresample: YES (ver 4.0.0)
DirectShow: YES
Media Foundation: YES
Parallel framework: Concurrency
Trace: YES (with Intel ITT)
Other third-party libraries:
Intel IPP: 2019.0.0 Gold [2019.0.0]
Intel IPP IW: sources (2019.0.0)

Install to: C:/opencv4build/install

-----------------------------------------------------------------

Code of opencv 4 performance comparison sample 

If you want to run the code. The problem is to use own detection cascade instead of cascade25.xml. This cascade is my own train to detect head and shoulders mainly from top view. This is not even top view but still there are some detections. Parameters (detectorBody.detectMultiScale(img, human, 1.4, 3, 0 | 1, Size(30,30), Size(120, 120));. ) are also not optimal but perform very fast on CPU and for comparison purpuse only. 

Opencv 3 vs Opencv 4 diferrence 

Warning focus on difference between opencv 3 and opencv 4

CV_CAP_OPENNI_BGR_IMAGE as CAP_OPENNI_BGR_IMAGE
CV_BGR2GRAY   as    COLOR_BGR2GRAY
opencv 3
outputVideo.open("video3.wmv", CV_FOURCC('W', 'M', 'V', '2'), cap.get(CV_CAP_PROP_FPS), Size(640, 480), true);


opencv 4
outputVideo.open("video3.wmv", VideoWriter::fourcc('W', 'M', 'V', '2'), cap.get(CAP_PROP_FPS), Size(640, 480), true);


Opencv 4.0 head detection, tutorial code example 

Almost everithink is the same. This is the reason why there is only function det(). Focus on parts described in Opencv 3 vs Opencv 4 diferrence chapter.



#include "pch.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <fstream>
#include <sstream>
#include "opencv2/objdetect\objdetect.hpp"
using namespace cv;
using namespace std;
string to_strin(double x) {
 ostringstream x_convert;
 x_convert << x;
 return x_convert.str();
}
int det()
{
 // prepare video input
 VideoCapture cap("mo.mov");
 // prepare video output
 VideoWriter outputVideo;
 outputVideo.open("video3.wmv"VideoWriter::fourcc('W''M''V''2'),
        cap.get(CAP_PROP_FPS), Size(640480), true);
 // prepare cascadeClassifier
 CascadeClassifier detectorBody;
 // !! Put your cascade or opencv cascede into project folder !!
 string cascadeName1 = "cascade25.xml";
 // Load cascade into CascadeClassifier
 bool loaded1 = detectorBody.load(cascadeName1);
 // Basic video input loop
 for (;;)
 {
  bool Is = cap.grab();
  if (Is == false) {
   cout << "Video Capture Fail" << endl;
   break;
  }
  else {
   // Just for measure time   
   const clock_t begin_time = clock();
   // Store results in these 2 vectors
   vector human;
   vector upperBody;
   // prepare 2 Mat container
   Mat img;
   Mat original;
   // capture frame from video file
   cap.retrieve(img, CAP_OPENNI_BGR_IMAGE);
   // Resize image if you want with same size as your VideoWriter
   resize(img, img, Size(640480));
   // Store original colored image
   img.copyTo(original);
   // color to gray image
   cvtColor(img, img, COLOR_BGR2GRAY);
   // detect people, more remarks in performace section  
   detectorBody.detectMultiScale(img, human, 1.43,
                                    0 | 1Size(3030), Size(120120));
   // Draw results from detectorBody into original colored image
   if (human.size() > 0) {
    for (int gg = 0; gg < human.size(); gg++) {
        rectangle(original, human[gg].tl(),
                                    human[gg].br(), Scalar(00255), 280);
    }
   }
          
   // measure time as current - begin_time
   clock_t diff = clock() - begin_time;
   // convert time into string
   //char buffer[126];
   //sprintf(buffer, "%d", diff);
   // display TIME ms on original image
   double ms = (double)diff;
   
   string mmm = to_strin(ms);
   putText(original, mmm, Point(10020), 12
                               Scalar(255255255), 280);
   putText(original, "ms"Point(15020), 12,
                               Scalar(255255255), 280);
   // draw results
   namedWindow("prew", WINDOW_AUTOSIZE);
   imshow("prew", original);
   // make video output
   outputVideo << original;
   int key1 = waitKey(20);
  }
 }
}
int main(int argcchar** argv)
{
 det();
 return 0;
}
Next Post Previous Post
2 Comments
  • Unknown
    Unknown April 3, 2019 at 6:24 AM

    where is cascade25.xml ?

  • Pornhub
    Pornhub November 20, 2019 at 12:27 AM

    nice post Thx เกมออฟไลน์

Add Comment
comment url