forked from MasteringOpenCV/code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
detectObject.cpp
executable file
·132 lines (116 loc) · 6.5 KB
/
detectObject.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*****************************************************************************
* Face Recognition using Eigenfaces or Fisherfaces
******************************************************************************
* by Shervin Emami, 5th Dec 2012
* http://www.shervinemami.info/openCV.html
******************************************************************************
* Ch8 of the book "Mastering OpenCV with Practical Computer Vision Projects"
* Copyright Packt Publishing 2012.
* http://www.packtpub.com/cool-projects-with-opencv/book
*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////
// detectObject.cpp, by Shervin Emami (www.shervinemami.info) on 30th May 2012.
// Easily detect objects such as faces or eyes (using LBP or Haar Cascades).
//////////////////////////////////////////////////////////////////////////////////////
#include "detectObject.h" // Easily detect faces or eyes (using LBP or Haar Cascades).
// Search for objects such as faces in the image using the given parameters, storing the multiple cv::Rects into 'objects'.
// Can use Haar cascades or LBP cascades for Face Detection, or even eye, mouth, or car detection.
// Input is temporarily shrunk to 'scaledWidth' for much faster detection, since 200 is enough to find faces.
void detectObjectsCustom(const Mat &img, CascadeClassifier &cascade, vector<Rect> &objects, int scaledWidth, int flags, Size minFeatureSize, float searchScaleFactor, int minNeighbors)
{
// If the input image is not grayscale, then convert the BGR or BGRA color image to grayscale.
Mat gray;
if (img.channels() == 3) {
cvtColor(img, gray, CV_BGR2GRAY);
}
else if (img.channels() == 4) {
cvtColor(img, gray, CV_BGRA2GRAY);
}
else {
// Access the input image directly, since it is already grayscale.
gray = img;
}
// Possibly shrink the image, to run much faster.
Mat inputImg;
float scale = img.cols / (float)scaledWidth;
if (img.cols > scaledWidth) {
// Shrink the image while keeping the same aspect ratio.
int scaledHeight = cvRound(img.rows / scale);
resize(gray, inputImg, Size(scaledWidth, scaledHeight));
}
else {
// Access the input image directly, since it is already small.
inputImg = gray;
}
// Standardize the brightness and contrast to improve dark images.
Mat equalizedImg;
equalizeHist(inputImg, equalizedImg);
// Detect objects in the small grayscale image.
cascade.detectMultiScale(equalizedImg, objects, searchScaleFactor, minNeighbors, flags, minFeatureSize);
// Enlarge the results if the image was temporarily shrunk before detection.
if (img.cols > scaledWidth) {
for (int i = 0; i < (int)objects.size(); i++ ) {
objects[i].x = cvRound(objects[i].x * scale);
objects[i].y = cvRound(objects[i].y * scale);
objects[i].width = cvRound(objects[i].width * scale);
objects[i].height = cvRound(objects[i].height * scale);
}
}
// Make sure the object is completely within the image, in case it was on a border.
for (int i = 0; i < (int)objects.size(); i++ ) {
if (objects[i].x < 0)
objects[i].x = 0;
if (objects[i].y < 0)
objects[i].y = 0;
if (objects[i].x + objects[i].width > img.cols)
objects[i].x = img.cols - objects[i].width;
if (objects[i].y + objects[i].height > img.rows)
objects[i].y = img.rows - objects[i].height;
}
// Return with the detected face rectangles stored in "objects".
}
// Search for just a single object in the image, such as the largest face, storing the result into 'largestObject'.
// Can use Haar cascades or LBP cascades for Face Detection, or even eye, mouth, or car detection.
// Input is temporarily shrunk to 'scaledWidth' for much faster detection, since 200 is enough to find faces.
// Note: detectLargestObject() should be faster than detectManyObjects().
void detectLargestObject(const Mat &img, CascadeClassifier &cascade, Rect &largestObject, int scaledWidth)
{
// Only search for just 1 object (the biggest in the image).
int flags = CASCADE_FIND_BIGGEST_OBJECT;// | CASCADE_DO_ROUGH_SEARCH;
// Smallest object size.
Size minFeatureSize = Size(20, 20);
// How detailed should the search be. Must be larger than 1.0.
float searchScaleFactor = 1.1f;
// How much the detections should be filtered out. This should depend on how bad false detections are to your system.
// minNeighbors=2 means lots of good+bad detections, and minNeighbors=6 means only good detections are given but some are missed.
int minNeighbors = 4;
// Perform Object or Face Detection, looking for just 1 object (the biggest in the image).
vector<Rect> objects;
detectObjectsCustom(img, cascade, objects, scaledWidth, flags, minFeatureSize, searchScaleFactor, minNeighbors);
if (objects.size() > 0) {
// Return the only detected object.
largestObject = (Rect)objects.at(0);
}
else {
// Return an invalid rect.
largestObject = Rect(-1,-1,-1,-1);
}
}
// Search for many objects in the image, such as all the faces, storing the results into 'objects'.
// Can use Haar cascades or LBP cascades for Face Detection, or even eye, mouth, or car detection.
// Input is temporarily shrunk to 'scaledWidth' for much faster detection, since 200 is enough to find faces.
// Note: detectLargestObject() should be faster than detectManyObjects().
void detectManyObjects(const Mat &img, CascadeClassifier &cascade, vector<Rect> &objects, int scaledWidth)
{
// Search for many objects in the one image.
int flags = CASCADE_SCALE_IMAGE;
// Smallest object size.
Size minFeatureSize = Size(20, 20);
// How detailed should the search be. Must be larger than 1.0.
float searchScaleFactor = 1.1f;
// How much the detections should be filtered out. This should depend on how bad false detections are to your system.
// minNeighbors=2 means lots of good+bad detections, and minNeighbors=6 means only good detections are given but some are missed.
int minNeighbors = 4;
// Perform Object or Face Detection, looking for many objects in the one image.
detectObjectsCustom(img, cascade, objects, scaledWidth, flags, minFeatureSize, searchScaleFactor, minNeighbors);
}