Skip to content

Commit 21573d5

Browse files
Merge pull request spmallick#486 from vkoriukina/vk/face_detection_comparision_dnn_gpu_update
FaceDetectionComparison: added DNN GPU usage
2 parents d4c2365 + 5f85ce9 commit 21573d5

13 files changed

+1016
-468
lines changed

FaceDetectionComparison/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
cmake_minimum_required(VERSION 2.8.12)
2+
set(CMAKE_CXX_STANDARD 11)
3+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
24

35
PROJECT(face_detection)
46

57
find_package( OpenCV REQUIRED )
68

7-
include_directories( ${OpenCV_INCLUDE_DIRS})
9+
message(STATUS "OpenCV library status:")
10+
message(STATUS " config: ${OpenCV_DIR}")
11+
message(STATUS " version: ${OpenCV_VERSION}")
12+
message(STATUS " libraries: ${OpenCV_LIBS}")
13+
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
814

15+
include_directories( ${OpenCV_INCLUDE_DIRS})
916
include(./dlib/dlib/cmake)
1017

1118
MACRO(add_example name)

FaceDetectionComparison/README.md

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,130 @@
1-
There are 10 code files in this repo - 5 for C++ and 5 for Python
1+
There are 10 code files in this repo - 5 for C++ and 5 for Python:
2+
23
1. face_detection_opencv_haar.cpp and face_detection_opencv_haar.py - For Haar based face detection
34
2. face_detection_opencv_dnn.cpp and face_detection_opencv_dnn.py - For OpenCV DNN based face detection
45
3. face_detection_dlib_hog.cpp and face_detection_dlib_hog.py - for dlib hog based face detection
56
4. face_detection_dlib_mmod.cpp and face_detection_dlib_mmod.py - for dlib mmod based face detection
67
5. run-all.cpp and run-all.py - for running all the 4 together
78

8-
99
First of all Unzip the dlib.zip file
1010

1111
## For C++
12+
1213
**Compile**
13-
cmake .
14+
15+
Add path to the properly build OpenCV with DNN GPU Support and your CUDA:
16+
17+
```
18+
cmake -D OpenCV_DIR=~/opencv -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda/ .
1419
make
20+
```
21+
22+
## For Python
23+
24+
_Note_: Our code is tested using Python 3.7.5, but it should also work with any other python3.x.
25+
26+
Install virtualenv:
27+
28+
```
29+
pip install virtualenv
30+
```
31+
32+
Create new virtual environment `env` and activate it:
33+
34+
```
35+
python -m venv env
36+
source env/bin/activate
37+
```
38+
39+
Install numpy:
40+
41+
```
42+
pip install numpy
43+
```
44+
45+
Install dlib:
46+
47+
```
48+
pip install dlib
49+
```
50+
51+
Create symlink to the properly build OpenCV with DNN GPU Support:
52+
53+
```
54+
cd env/lib/python3.x/site-packages/
55+
ln -s ~/opencv/build/cv2.so cv2.so
56+
```
1557

1658
## Run
17-
**If you dont give any filename, it will use the webcam**
59+
60+
**If you don't pass any filename, it will use the web cam**
1861

1962
### For individual face detectors
63+
2064
**C++**
65+
66+
```
2167
./face_detection_XXXX <filename>
68+
```
69+
70+
_Note:_ for `face_detection_opencv_dnn.cpp` you can pass up to 3 arguments:
71+
72+
- video filename, if you'd like to run inference on a video instead of a camera:
73+
74+
```
75+
./face_detection_opencv_dnn.out <filename>
76+
```
77+
78+
- device, if you want to use CPU instead of CPU:
79+
80+
```
81+
./face_detection_opencv_dnn.out "" cpu
82+
```
83+
84+
- framework to specify Caffe (caffe) or TensorFlow (tf) network to use. Caffe network is set by default:
85+
86+
```
87+
./face_detection_opencv_dnn.out "" gpu tf
88+
```
2289

2390
**Python**
24-
python face_detection_XXXX.py <filename>
91+
92+
```
93+
python face_detection_XXXX.py -video <filename>
94+
```
95+
96+
_Note:_ for `face_detection_opencv_dnn.py` you can pass up to 3 arguments:
97+
98+
- filename, if you'd like to run inference on a video instead of a camera:
99+
100+
```
101+
python face_detection_opencv_dnn.out --video <filename>
102+
```
103+
104+
- device, if you want to use CPU instead of GPU:
105+
106+
```
107+
python face_detection_opencv_dnn.out --video <filename> --device cpu
108+
```
109+
110+
- framework to specify Caffe (caffe) or TensorFlow (tf) network to use. Caffe network is set by default:
111+
112+
```
113+
python face_detection_opencv_dnn.out --video <filename> --device cpu --framework tf
114+
```
25115

26116
### For running all together
27-
**C++**
28-
./run-all <filename>
29117

30-
**Python**
31-
run-all.py <filename>
118+
**C++** ./run-all <filename>
32119

120+
**Python** python run-all.py --video <filename>
33121

34122
# AI Courses by OpenCV
35123

36-
Want to become an expert in AI? [AI Courses by OpenCV](https://opencv.org/courses/) is a great place to start.
124+
Want to become an expert in AI? [AI Courses by OpenCV](https://opencv.org/courses/) is a great place to start.
37125

38126
<a href="https://opencv.org/courses/">
39-
<p align="center">
127+
<p align="center">
40128
<img src="https://www.learnopencv.com/wp-content/uploads/2020/04/AI-Courses-By-OpenCV-Github.png">
41129
</p>
42130
</a>

FaceDetectionComparison/dlib.zip

-824 KB
Binary file not shown.

FaceDetectionComparison/face_detection_dlib_hog.cpp

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -36,44 +36,49 @@ void detectFaceDlibHog(frontal_face_detector hogFaceDetector, Mat &frameDlibHog,
3636

3737
for ( size_t i = 0; i < faceRects.size(); i++ )
3838
{
39-
int x1 = (int)(faceRects[i].left() * scaleWidth);
40-
int y1 = (int)(faceRects[i].top() * scaleHeight);
41-
int x2 = (int)(faceRects[i].right() * scaleWidth);
42-
int y2 = (int)(faceRects[i].bottom() * scaleHeight);
43-
cv::rectangle(frameDlibHog, Point(x1, y1), Point(x2, y2), Scalar(0,255,0), (int)(frameHeight/150.0), 4);
39+
int x1 = (int)(faceRects[i].left() * scaleWidth);
40+
int y1 = (int)(faceRects[i].top() * scaleHeight);
41+
int x2 = (int)(faceRects[i].right() * scaleWidth);
42+
int y2 = (int)(faceRects[i].bottom() * scaleHeight);
43+
cv::rectangle(frameDlibHog, Point(x1, y1), Point(x2, y2), Scalar(0,255,0), (int)(frameHeight/150.0), 4);
4444
}
4545
}
4646

47+
4748
int main( int argc, const char** argv )
4849
{
49-
frontal_face_detector hogFaceDetector = get_frontal_face_detector();
50-
51-
VideoCapture source;
52-
if (argc == 1)
53-
source.open(0);
54-
else
55-
source.open(argv[1]);
56-
Mat frame;
57-
58-
double tt_dlibHog = 0;
59-
double fpsDlibHog = 0;
60-
while(1)
61-
{
62-
source >> frame;
63-
if(frame.empty())
64-
break;
65-
66-
double t = cv::getTickCount();
67-
detectFaceDlibHog ( hogFaceDetector, frame );
68-
tt_dlibHog = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
69-
fpsDlibHog = 1/tt_dlibHog;
70-
putText(frame, format("DLIB HoG ; FPS = %.2f",fpsDlibHog), Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.4, Scalar(0, 0, 255), 4);
71-
imshow( "DLIB - HoG Face Detection", frame );
72-
int k = waitKey(5);
73-
if(k == 27)
74-
{
75-
destroyAllWindows();
76-
break;
50+
frontal_face_detector hogFaceDetector = get_frontal_face_detector();
51+
52+
VideoCapture source;
53+
if (argc == 1)
54+
source.open(0, CAP_V4L);
55+
else
56+
source.open(argv[1]);
57+
58+
Mat frame;
59+
60+
double tt_dlibHog = 0;
61+
double fpsDlibHog = 0;
62+
63+
while (true)
64+
{
65+
source >> frame;
66+
if (frame.empty())
67+
break;
68+
69+
double t = cv::getTickCount();
70+
detectFaceDlibHog(hogFaceDetector, frame);
71+
tt_dlibHog = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
72+
fpsDlibHog = 1/tt_dlibHog;
73+
74+
putText(frame, format("DLIB HoG; FPS = %.2f",fpsDlibHog), Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.3, Scalar(0, 0, 255), 4);
75+
imshow("DLIB - HoG Face Detection", frame);
76+
77+
int k = waitKey(5);
78+
if(k == 27)
79+
{
80+
destroyAllWindows();
81+
break;
82+
}
7783
}
78-
}
7984
}
Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
from __future__ import division
1+
import argparse
2+
import os
3+
import time
4+
25
import cv2
36
import dlib
4-
import time
5-
import sys
7+
68

79
def detectFaceDlibHog(detector, frame, inHeight=300, inWidth=0):
810

911
frameDlibHog = frame.copy()
1012
frameHeight = frameDlibHog.shape[0]
1113
frameWidth = frameDlibHog.shape[1]
1214
if not inWidth:
13-
inWidth = int((frameWidth / frameHeight)*inHeight)
15+
inWidth = int((frameWidth / frameHeight) * inHeight)
1416

1517
scaleHeight = frameHeight / inHeight
1618
scaleWidth = frameWidth / inWidth
@@ -23,48 +25,89 @@ def detectFaceDlibHog(detector, frame, inHeight=300, inWidth=0):
2325
bboxes = []
2426
for faceRect in faceRects:
2527

26-
cvRect = [int(faceRect.left()*scaleWidth), int(faceRect.top()*scaleHeight),
27-
int(faceRect.right()*scaleWidth), int(faceRect.bottom()*scaleHeight) ]
28+
cvRect = [
29+
int(faceRect.left() * scaleWidth),
30+
int(faceRect.top() * scaleHeight),
31+
int(faceRect.right() * scaleWidth),
32+
int(faceRect.bottom() * scaleHeight),
33+
]
2834
bboxes.append(cvRect)
29-
cv2.rectangle(frameDlibHog, (cvRect[0], cvRect[1]), (cvRect[2], cvRect[3]), (0, 255, 0), int(round(frameHeight/150)), 4)
35+
cv2.rectangle(
36+
frameDlibHog,
37+
(cvRect[0], cvRect[1]),
38+
(cvRect[2], cvRect[3]),
39+
(0, 255, 0),
40+
int(round(frameHeight / 150)),
41+
4,
42+
)
3043
return frameDlibHog, bboxes
3144

32-
if __name__ == "__main__" :
45+
46+
if __name__ == "__main__":
47+
48+
parser = argparse.ArgumentParser(description="Face detection")
49+
parser.add_argument("--video", type=str, default="", help="Path to video file")
50+
args = parser.parse_args()
51+
52+
source = args.video
3353
hogFaceDetector = dlib.get_frontal_face_detector()
3454

35-
source = 0
36-
if len(sys.argv) > 1:
37-
source = sys.argv[1]
55+
outputFolder = "output-hog-videos"
56+
if not os.path.exists(outputFolder):
57+
os.makedirs(outputFolder)
3858

39-
cap = cv2.VideoCapture(source)
59+
if source:
60+
cap = cv2.VideoCapture(source)
61+
outputFile = os.path.basename(source)[:-4] + ".avi"
62+
else:
63+
cap = cv2.VideoCapture(0, cv2.CAP_V4L)
64+
outputFile = "grabbed_from_camera.avi"
4065
hasFrame, frame = cap.read()
4166

42-
vid_writer = cv2.VideoWriter('output-hog-{}.avi'.format(str(source).split(".")[0]),cv2.VideoWriter_fourcc('M','J','P','G'), 15, (frame.shape[1],frame.shape[0]))
67+
vid_writer = cv2.VideoWriter(
68+
os.path.join(outputFolder, outputFile),
69+
cv2.VideoWriter_fourcc("M", "J", "P", "G"),
70+
15,
71+
(frame.shape[1], frame.shape[0]),
72+
)
4373

4474
frame_count = 0
4575
tt_dlibHog = 0
46-
while(1):
76+
77+
while True:
4778
hasFrame, frame = cap.read()
4879
if not hasFrame:
4980
break
50-
frame_count += 1
5181

82+
frame_count += 1
5283
t = time.time()
53-
outDlibHog, bboxes = detectFaceDlibHog(hogFaceDetector,frame)
84+
85+
outDlibHog, bboxes = detectFaceDlibHog(hogFaceDetector, frame)
5486
tt_dlibHog += time.time() - t
5587
fpsDlibHog = frame_count / tt_dlibHog
5688

57-
label = "DLIB HoG ; ; FPS : {:.2f}".format(fpsDlibHog)
58-
cv2.putText(outDlibHog, label, (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.4, (0, 0, 255), 3, cv2.LINE_AA)
89+
label = "DLIB HoG; FPS : {:.2f}".format(fpsDlibHog)
90+
cv2.putText(
91+
outDlibHog,
92+
label,
93+
(10, 50),
94+
cv2.FONT_HERSHEY_SIMPLEX,
95+
1.3,
96+
(0, 0, 255),
97+
3,
98+
cv2.LINE_AA,
99+
)
59100

60101
cv2.imshow("Face Detection Comparison", outDlibHog)
61102

62103
vid_writer.write(outDlibHog)
104+
63105
if frame_count == 1:
64106
tt_dlibHog = 0
65107

66-
k = cv2.waitKey(10)
108+
k = cv2.waitKey(5)
67109
if k == 27:
68110
break
111+
69112
cv2.destroyAllWindows()
70113
vid_writer.release()

0 commit comments

Comments
 (0)