Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
379dcf87
Commit
379dcf87
authored
Feb 21, 2013
by
Oscar Deniz Suarez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added smile detector
parent
39baa223
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
282 additions
and
0 deletions
+282
-0
haarcascade_smile.xml
data/haarcascades/haarcascade_smile.xml
+0
-0
smiledetect.cpp
samples/c/smiledetect.cpp
+282
-0
No files found.
data/haarcascades/haarcascade_smile.xml
0 → 100644
View file @
379dcf87
This source diff could not be displayed because it is too large. You can
view the blob
instead.
samples/c/smiledetect.cpp
0 → 100644
View file @
379dcf87
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <iterator>
#include <stdio.h>
using
namespace
std
;
using
namespace
cv
;
static
void
help
()
{
cout
<<
"
\n
This program demonstrates the smile detector.
\n
"
"Usage:
\n
"
"./smiledetect [--cascade=<cascade_path> this is the frontal face classifier]
\n
"
" [--smile-cascade[=smile_cascade_path]]
\n
"
" [--scale=<image scale greater or equal to 1, try 1.3 for example. The larger the faster the processing>]
\n
"
" [--try-flip]
\n
"
" [filename|camera_index]
\n\n
"
"Example:
\n
"
"./smiledetect --cascade=
\"
../../data/haarcascades/haarcascade_frontalface_alt.xml
\"
--smile-cascade=
\"
../../data/haarcascades/haarcascade_smile.xml
\"
--scale=1.3
\n\n
"
"During execution:
\n\t
Hit any key to quit.
\n
"
"
\t
Using OpenCV version "
<<
CV_VERSION
<<
"
\n
"
<<
endl
;
}
void
detectAndDraw
(
Mat
&
img
,
CascadeClassifier
&
cascade
,
CascadeClassifier
&
nestedCascade
,
double
scale
,
bool
tryflip
);
string
cascadeName
=
"../../data/haarcascades/haarcascade_frontalface_alt.xml"
;
string
nestedCascadeName
=
"../../data/haarcascades/haarcascade_smile.xml"
;
// The number of detected neighbors depends on image size, these are for performing an approximate mapping to a maximum number of neighbors
const
float
coef1
=
0.3190
;
const
float
coef2
=
-
48.7187
;
int
main
(
int
argc
,
const
char
**
argv
)
{
CvCapture
*
capture
=
0
;
Mat
frame
,
frameCopy
,
image
;
const
string
scaleOpt
=
"--scale="
;
size_t
scaleOptLen
=
scaleOpt
.
length
();
const
string
cascadeOpt
=
"--cascade="
;
size_t
cascadeOptLen
=
cascadeOpt
.
length
();
const
string
nestedCascadeOpt
=
"--smile-cascade"
;
size_t
nestedCascadeOptLen
=
nestedCascadeOpt
.
length
();
const
string
tryFlipOpt
=
"--try-flip"
;
size_t
tryFlipOptLen
=
tryFlipOpt
.
length
();
string
inputName
;
bool
tryflip
=
false
;
help
();
CascadeClassifier
cascade
,
nestedCascade
;
double
scale
=
1
;
for
(
int
i
=
1
;
i
<
argc
;
i
++
)
{
cout
<<
"Processing "
<<
i
<<
" "
<<
argv
[
i
]
<<
endl
;
if
(
cascadeOpt
.
compare
(
0
,
cascadeOptLen
,
argv
[
i
],
cascadeOptLen
)
==
0
)
{
cascadeName
.
assign
(
argv
[
i
]
+
cascadeOptLen
);
cout
<<
" from which we have cascadeName= "
<<
cascadeName
<<
endl
;
}
else
if
(
nestedCascadeOpt
.
compare
(
0
,
nestedCascadeOptLen
,
argv
[
i
],
nestedCascadeOptLen
)
==
0
)
{
if
(
argv
[
i
][
nestedCascadeOpt
.
length
()]
==
'='
)
nestedCascadeName
.
assign
(
argv
[
i
]
+
nestedCascadeOpt
.
length
()
+
1
);
if
(
!
nestedCascade
.
load
(
nestedCascadeName
)
)
cerr
<<
"WARNING: Could not load classifier cascade for nested objects"
<<
endl
;
}
else
if
(
scaleOpt
.
compare
(
0
,
scaleOptLen
,
argv
[
i
],
scaleOptLen
)
==
0
)
{
if
(
!
sscanf
(
argv
[
i
]
+
scaleOpt
.
length
(),
"%lf"
,
&
scale
)
||
scale
<
1
)
scale
=
1
;
cout
<<
" from which we read scale = "
<<
scale
<<
endl
;
}
else
if
(
tryFlipOpt
.
compare
(
0
,
tryFlipOptLen
,
argv
[
i
],
tryFlipOptLen
)
==
0
)
{
tryflip
=
true
;
cout
<<
" will try to flip image horizontally to detect assymetric objects
\n
"
;
}
else
if
(
argv
[
i
][
0
]
==
'-'
)
{
cerr
<<
"WARNING: Unknown option "
<<
argv
[
i
]
<<
endl
;
}
else
inputName
.
assign
(
argv
[
i
]
);
}
if
(
!
cascade
.
load
(
cascadeName
)
)
{
cerr
<<
"ERROR: Could not load classifier cascade"
<<
endl
;
help
();
return
-
1
;
}
if
(
inputName
.
empty
()
||
(
isdigit
(
inputName
.
c_str
()[
0
])
&&
inputName
.
c_str
()[
1
]
==
'\0'
)
)
{
capture
=
cvCaptureFromCAM
(
inputName
.
empty
()
?
0
:
inputName
.
c_str
()[
0
]
-
'0'
);
int
c
=
inputName
.
empty
()
?
0
:
inputName
.
c_str
()[
0
]
-
'0'
;
if
(
!
capture
)
cout
<<
"Capture from CAM "
<<
c
<<
" didn't work"
<<
endl
;
}
else
if
(
inputName
.
size
()
)
{
image
=
imread
(
inputName
,
1
);
if
(
image
.
empty
()
)
{
capture
=
cvCaptureFromAVI
(
inputName
.
c_str
()
);
if
(
!
capture
)
cout
<<
"Capture from AVI didn't work"
<<
endl
;
}
}
else
{
image
=
imread
(
"lena.jpg"
,
1
);
if
(
image
.
empty
())
cout
<<
"Couldn't read lena.jpg"
<<
endl
;
}
cvNamedWindow
(
"result"
,
1
);
if
(
capture
)
{
cout
<<
"In capture ..."
<<
endl
;
for
(;;)
{
IplImage
*
iplImg
=
cvQueryFrame
(
capture
);
frame
=
iplImg
;
if
(
frame
.
empty
()
)
break
;
if
(
iplImg
->
origin
==
IPL_ORIGIN_TL
)
frame
.
copyTo
(
frameCopy
);
else
flip
(
frame
,
frameCopy
,
0
);
detectAndDraw
(
frameCopy
,
cascade
,
nestedCascade
,
scale
,
tryflip
);
if
(
waitKey
(
10
)
>=
0
)
goto
_cleanup_
;
}
waitKey
(
0
);
_cleanup_:
cvReleaseCapture
(
&
capture
);
}
else
{
cout
<<
"In image read"
<<
endl
;
if
(
!
image
.
empty
()
)
{
detectAndDraw
(
image
,
cascade
,
nestedCascade
,
scale
,
tryflip
);
waitKey
(
0
);
}
else
if
(
!
inputName
.
empty
()
)
{
/* assume it is a text file containing the
list of the image filenames to be processed - one per line */
FILE
*
f
=
fopen
(
inputName
.
c_str
(),
"rt"
);
if
(
f
)
{
char
buf
[
1000
+
1
];
while
(
fgets
(
buf
,
1000
,
f
)
)
{
int
len
=
(
int
)
strlen
(
buf
),
c
;
while
(
len
>
0
&&
isspace
(
buf
[
len
-
1
])
)
len
--
;
buf
[
len
]
=
'\0'
;
cout
<<
"file "
<<
buf
<<
endl
;
image
=
imread
(
buf
,
1
);
if
(
!
image
.
empty
()
)
{
detectAndDraw
(
image
,
cascade
,
nestedCascade
,
scale
,
tryflip
);
c
=
waitKey
(
0
);
if
(
c
==
27
||
c
==
'q'
||
c
==
'Q'
)
break
;
}
else
{
cerr
<<
"Aw snap, couldn't read image "
<<
buf
<<
endl
;
}
}
fclose
(
f
);
}
}
}
cvDestroyWindow
(
"result"
);
return
0
;
}
void
detectAndDraw
(
Mat
&
img
,
CascadeClassifier
&
cascade
,
CascadeClassifier
&
nestedCascade
,
double
scale
,
bool
tryflip
)
{
int
i
=
0
;
vector
<
Rect
>
faces
,
faces2
;
const
static
Scalar
colors
[]
=
{
CV_RGB
(
0
,
0
,
255
),
CV_RGB
(
0
,
128
,
255
),
CV_RGB
(
0
,
255
,
255
),
CV_RGB
(
0
,
255
,
0
),
CV_RGB
(
255
,
128
,
0
),
CV_RGB
(
255
,
255
,
0
),
CV_RGB
(
255
,
0
,
0
),
CV_RGB
(
255
,
0
,
255
)}
;
Mat
gray
,
smallImg
(
cvRound
(
img
.
rows
/
scale
),
cvRound
(
img
.
cols
/
scale
),
CV_8UC1
);
const
int
max_neighbors
=
MAX
(
0
,
cvRound
((
float
)
coef1
*
smallImg
.
cols
+
coef2
));
cvtColor
(
img
,
gray
,
CV_BGR2GRAY
);
resize
(
gray
,
smallImg
,
smallImg
.
size
(),
0
,
0
,
INTER_LINEAR
);
equalizeHist
(
smallImg
,
smallImg
);
cascade
.
detectMultiScale
(
smallImg
,
faces
,
1.1
,
2
,
0
//|CV_HAAR_FIND_BIGGEST_OBJECT
//|CV_HAAR_DO_ROUGH_SEARCH
|
CV_HAAR_SCALE_IMAGE
,
Size
(
30
,
30
)
);
if
(
tryflip
)
{
flip
(
smallImg
,
smallImg
,
1
);
cascade
.
detectMultiScale
(
smallImg
,
faces2
,
1.1
,
2
,
0
//|CV_HAAR_FIND_BIGGEST_OBJECT
//|CV_HAAR_DO_ROUGH_SEARCH
|
CV_HAAR_SCALE_IMAGE
,
Size
(
30
,
30
)
);
for
(
vector
<
Rect
>::
const_iterator
r
=
faces2
.
begin
();
r
!=
faces2
.
end
();
r
++
)
{
faces
.
push_back
(
Rect
(
smallImg
.
cols
-
r
->
x
-
r
->
width
,
r
->
y
,
r
->
width
,
r
->
height
));
}
}
for
(
vector
<
Rect
>::
iterator
r
=
faces
.
begin
();
r
!=
faces
.
end
();
r
++
,
i
++
)
{
Mat
smallImgROI
;
vector
<
Rect
>
nestedObjects
;
Point
center
;
Scalar
color
=
colors
[
i
%
8
];
int
radius
;
double
aspect_ratio
=
(
double
)
r
->
width
/
r
->
height
;
if
(
0.75
<
aspect_ratio
&&
aspect_ratio
<
1.3
)
{
center
.
x
=
cvRound
((
r
->
x
+
r
->
width
*
0.5
)
*
scale
);
center
.
y
=
cvRound
((
r
->
y
+
r
->
height
*
0.5
)
*
scale
);
radius
=
cvRound
((
r
->
width
+
r
->
height
)
*
0.25
*
scale
);
circle
(
img
,
center
,
radius
,
color
,
3
,
8
,
0
);
}
else
rectangle
(
img
,
cvPoint
(
cvRound
(
r
->
x
*
scale
),
cvRound
(
r
->
y
*
scale
)),
cvPoint
(
cvRound
((
r
->
x
+
r
->
width
-
1
)
*
scale
),
cvRound
((
r
->
y
+
r
->
height
-
1
)
*
scale
)),
color
,
3
,
8
,
0
);
if
(
nestedCascade
.
empty
()
)
continue
;
const
int
half_height
=
cvRound
((
float
)
r
->
height
/
2
);
r
->
y
=
r
->
y
+
half_height
;
r
->
height
=
half_height
;
smallImgROI
=
smallImg
(
*
r
);
nestedCascade
.
detectMultiScale
(
smallImgROI
,
nestedObjects
,
1.1
,
0
,
0
//|CV_HAAR_FIND_BIGGEST_OBJECT
//|CV_HAAR_DO_ROUGH_SEARCH
//|CV_HAAR_DO_CANNY_PRUNING
|
CV_HAAR_SCALE_IMAGE
,
Size
(
30
,
30
)
);
// Draw rectangle reflecting confidence
const
int
smile_neighbors
=
nestedObjects
.
size
();
cout
<<
"Detected "
<<
smile_neighbors
<<
" smile neighbors"
<<
endl
;
const
int
rect_height
=
cvRound
((
float
)
img
.
rows
*
smile_neighbors
/
max_neighbors
);
CvScalar
col
=
CV_RGB
((
float
)
255
*
smile_neighbors
/
max_neighbors
,
0
,
0
);
rectangle
(
img
,
cvPoint
(
0
,
img
.
rows
),
cvPoint
(
img
.
cols
/
10
,
img
.
rows
-
rect_height
),
col
,
-
1
);
}
cv
::
imshow
(
"result"
,
img
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment