Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
e9c765ee
O
Opencv
项目概览
Greenplum
/
Opencv
11 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e9c765ee
编写于
11月 12, 2014
作者:
S
Samyak Datta
提交者:
Dikay900
5月 26, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
C++ sample code to detect facial features
上级
83723c15
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
239 addition
and
0 deletion
+239
-0
samples/cpp/facial_features.cpp
samples/cpp/facial_features.cpp
+239
-0
未找到文件。
samples/cpp/facial_features.cpp
0 → 100644
浏览文件 @
e9c765ee
/*
* Author: Samyak Datta (datta[dot]samyak[at]gmail.com)
*
* A program to detect facial feature points using
* Haarcascade classifiers for face, eyes, nose and mouth
*
*/
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using
namespace
std
;
using
namespace
cv
;
// Functions to parse command-line arguments
static
string
getCommandOption
(
const
vector
<
string
>&
,
const
string
&
);
static
void
setCommandOptions
(
vector
<
string
>&
,
int
,
char
**
);
static
bool
doesCmdOptionExist
(
const
vector
<
string
>&
,
const
string
&
);
// Functions for facial feature detection
static
void
help
();
static
void
detectFaces
(
Mat
&
,
vector
<
Rect_
<
int
>
>&
,
string
);
static
void
detectEyes
(
Mat
&
,
vector
<
Rect_
<
int
>
>&
,
string
);
static
void
detectNose
(
Mat
&
,
vector
<
Rect_
<
int
>
>&
,
string
);
static
void
detectMouth
(
Mat
&
,
vector
<
Rect_
<
int
>
>&
,
string
);
static
void
detectFacialFeaures
(
Mat
&
,
const
vector
<
Rect_
<
int
>
>
,
string
,
string
,
string
);
string
input_image_path
;
string
face_cascade_path
,
eye_cascade_path
,
nose_cascade_path
,
mouth_cascade_path
;
int
main
(
int
argc
,
char
**
argv
)
{
if
(
argc
<
3
)
{
help
();
return
1
;
}
// Extract command-line options
vector
<
string
>
args
;
setCommandOptions
(
args
,
argc
,
argv
);
input_image_path
=
argv
[
1
];
face_cascade_path
=
argv
[
2
];
eye_cascade_path
=
(
doesCmdOptionExist
(
args
,
"-eyes"
))
?
getCommandOption
(
args
,
"-eyes"
)
:
""
;
nose_cascade_path
=
(
doesCmdOptionExist
(
args
,
"-nose"
))
?
getCommandOption
(
args
,
"-nose"
)
:
""
;
mouth_cascade_path
=
(
doesCmdOptionExist
(
args
,
"-mouth"
))
?
getCommandOption
(
args
,
"-mouth"
)
:
""
;
// Load image and cascade classifier files
Mat
image
;
image
=
imread
(
input_image_path
);
// Detect faces and facial features
vector
<
Rect_
<
int
>
>
faces
;
detectFaces
(
image
,
faces
,
face_cascade_path
);
detectFacialFeaures
(
image
,
faces
,
eye_cascade_path
,
nose_cascade_path
,
mouth_cascade_path
);
imshow
(
"Result"
,
image
);
waitKey
(
0
);
return
0
;
}
void
setCommandOptions
(
vector
<
string
>&
args
,
int
argc
,
char
**
argv
)
{
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
args
.
push_back
(
argv
[
i
]);
}
return
;
}
string
getCommandOption
(
const
vector
<
string
>&
args
,
const
string
&
opt
)
{
string
answer
;
vector
<
string
>::
const_iterator
it
=
find
(
args
.
begin
(),
args
.
end
(),
opt
);
if
(
it
!=
args
.
end
()
&&
(
++
it
!=
args
.
end
()))
answer
=
*
it
;
return
answer
;
}
bool
doesCmdOptionExist
(
const
vector
<
string
>&
args
,
const
string
&
opt
)
{
vector
<
string
>::
const_iterator
it
=
find
(
args
.
begin
(),
args
.
end
(),
opt
);
return
(
it
!=
args
.
end
());
}
static
void
help
()
{
cout
<<
"
\n
This file demonstrates facial feature points detection using Haarcascade classifiers.
\n
"
"The program detects a face and eyes, nose and mouth inside the face."
"The code has been tested on the Japanese Female Facial Expression (JAFFE) database and found"
"to give reasonably accurate results.
\n
"
;
cout
<<
"
\n
USAGE: ./cpp-example-facial_features [IMAGE] [FACE_CASCADE] [OPTIONS]
\n
"
"IMAGE
\n\t
Path to the image of a face taken as input.
\n
"
"FACE_CASCSDE
\n\t
Path to a haarcascade classifier for face detection.
\n
"
"OPTIONS:
\n
There are 3 options available which are described in detail. There must be a "
"space between the option and it's argument (All three options accept arguments).
\n
"
"
\t
-eyes : Specify the haarcascade classifier for eye detection.
\n
"
"
\t
-nose : Specify the haarcascade classifier for nose detection.
\n
"
"
\t
-mouth : Specify the haarcascade classifier for mouth detection.
\n
"
;
cout
<<
"EXAMPLE:
\n
"
"(1) ./cpp-example-facial_features image.jpg face.xml -eyes eyes.xml -mouth mouth.xml
\n
"
"
\t
This will detect the face, eyes and mouth in image.jpg.
\n
"
"(2) ./cpp-example-facial_features image.jpg face.xml -nose nose.xml
\n
"
"
\t
This will detect the face and nose in image.jpg.
\n
"
"(3) ./cpp-example-facial_features image.jpg face.xml
\n
"
"
\t
This will detect only the face in image.jpg.
\n
"
;
cout
<<
"
\n\n
The classifiers for face and eyes can be downloaded from : "
"
\n
https://github.com/Itseez/opencv/tree/master/data/haarcascades"
;
cout
<<
"
\n\n
The classifiers for nose and mouth can be downloaded from : "
"
\n
https://github.com/Itseez/opencv_contrib/tree/master/modules/face/data/cascades
\n
"
;
}
static
void
detectFaces
(
Mat
&
img
,
vector
<
Rect_
<
int
>
>&
faces
,
string
cascade_path
)
{
CascadeClassifier
face_cascade
;
face_cascade
.
load
(
cascade_path
);
face_cascade
.
detectMultiScale
(
img
,
faces
,
1.15
,
3
,
0
|
CASCADE_SCALE_IMAGE
,
Size
(
30
,
30
));
return
;
}
static
void
detectFacialFeaures
(
Mat
&
img
,
const
vector
<
Rect_
<
int
>
>
faces
,
string
eye_cascade
,
string
nose_cascade
,
string
mouth_cascade
)
{
for
(
unsigned
int
i
=
0
;
i
<
faces
.
size
();
++
i
)
{
// Mark the bounding box enclosing the face
Rect
face
=
faces
[
i
];
rectangle
(
img
,
Point
(
face
.
x
,
face
.
y
),
Point
(
face
.
x
+
face
.
width
,
face
.
y
+
face
.
height
),
Scalar
(
255
,
0
,
0
),
1
,
4
);
// Eyes, nose and mouth will be detected inside the face (region of interest)
Mat
ROI
=
img
(
Rect
(
face
.
x
,
face
.
y
,
face
.
width
,
face
.
height
));
// Check if all features (eyes, nose and mouth) are being detected
bool
is_full_detection
=
false
;
if
(
(
!
eye_cascade
.
empty
())
&&
(
!
nose_cascade
.
empty
())
&&
(
!
mouth_cascade
.
empty
())
)
is_full_detection
=
true
;
// Detect eyes if classifier provided by the user
if
(
!
eye_cascade
.
empty
())
{
vector
<
Rect_
<
int
>
>
eyes
;
detectEyes
(
ROI
,
eyes
,
eye_cascade
);
// Mark points corresponding to the centre of the eyes
for
(
unsigned
int
j
=
0
;
j
<
eyes
.
size
();
++
j
)
{
Rect
e
=
eyes
[
j
];
circle
(
ROI
,
Point
(
e
.
x
+
e
.
width
/
2
,
e
.
y
+
e
.
height
/
2
),
3
,
Scalar
(
0
,
255
,
0
),
-
1
,
8
);
/* rectangle(ROI, Point(e.x, e.y), Point(e.x+e.width, e.y+e.height),
Scalar(0, 255, 0), 1, 4); */
}
}
// Detect nose if classifier provided by the user
double
nose_center_height
=
0.0
;
if
(
!
nose_cascade
.
empty
())
{
vector
<
Rect_
<
int
>
>
nose
;
detectNose
(
ROI
,
nose
,
nose_cascade
);
// Mark points corresponding to the centre (tip) of the nose
for
(
unsigned
int
j
=
0
;
j
<
nose
.
size
();
++
j
)
{
Rect
n
=
nose
[
j
];
circle
(
ROI
,
Point
(
n
.
x
+
n
.
width
/
2
,
n
.
y
+
n
.
height
/
2
),
3
,
Scalar
(
0
,
255
,
0
),
-
1
,
8
);
nose_center_height
=
(
n
.
y
+
n
.
height
/
2
);
}
}
// Detect mouth if classifier provided by the user
double
mouth_center_height
=
0.0
;
if
(
!
mouth_cascade
.
empty
())
{
vector
<
Rect_
<
int
>
>
mouth
;
detectMouth
(
ROI
,
mouth
,
mouth_cascade
);
for
(
unsigned
int
j
=
0
;
j
<
mouth
.
size
();
++
j
)
{
Rect
m
=
mouth
[
j
];
mouth_center_height
=
(
m
.
y
+
m
.
height
/
2
);
// The mouth should lie below the nose
if
(
(
is_full_detection
)
&&
(
mouth_center_height
>
nose_center_height
)
)
{
rectangle
(
ROI
,
Point
(
m
.
x
,
m
.
y
),
Point
(
m
.
x
+
m
.
width
,
m
.
y
+
m
.
height
),
Scalar
(
0
,
255
,
0
),
1
,
4
);
}
else
if
(
(
is_full_detection
)
&&
(
mouth_center_height
<=
nose_center_height
)
)
continue
;
else
rectangle
(
ROI
,
Point
(
m
.
x
,
m
.
y
),
Point
(
m
.
x
+
m
.
width
,
m
.
y
+
m
.
height
),
Scalar
(
0
,
255
,
0
),
1
,
4
);
}
}
}
return
;
}
static
void
detectEyes
(
Mat
&
img
,
vector
<
Rect_
<
int
>
>&
eyes
,
string
cascade_path
)
{
CascadeClassifier
eyes_cascade
;
eyes_cascade
.
load
(
cascade_path
);
eyes_cascade
.
detectMultiScale
(
img
,
eyes
,
1.20
,
5
,
0
|
CASCADE_SCALE_IMAGE
,
Size
(
30
,
30
));
return
;
}
static
void
detectNose
(
Mat
&
img
,
vector
<
Rect_
<
int
>
>&
nose
,
string
cascade_path
)
{
CascadeClassifier
nose_cascade
;
nose_cascade
.
load
(
cascade_path
);
nose_cascade
.
detectMultiScale
(
img
,
nose
,
1.20
,
5
,
0
|
CASCADE_SCALE_IMAGE
,
Size
(
30
,
30
));
return
;
}
static
void
detectMouth
(
Mat
&
img
,
vector
<
Rect_
<
int
>
>&
mouth
,
string
cascade_path
)
{
CascadeClassifier
mouth_cascade
;
mouth_cascade
.
load
(
cascade_path
);
mouth_cascade
.
detectMultiScale
(
img
,
mouth
,
1.20
,
5
,
0
|
CASCADE_SCALE_IMAGE
,
Size
(
30
,
30
));
return
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录