summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>2017-11-26 17:24:56 -0800
committerReynaldo H. Verdejo Pinochet <reynaldo@freedesktop.org>2019-04-17 15:27:52 -0700
commit7f55dc4bc6c93e69dd6fda7cc3247b68f91affef (patch)
treebf0eee598ab9937f540852263a39d9c70fa80fcd
parentf10458fd1c14590cb27eb665d5f215bf2c5f57e4 (diff)
opencv: facedetect: add right/left ear detection
-rw-r--r--ext/opencv/gstfacedetect.cpp78
-rw-r--r--ext/opencv/gstfacedetect.h4
2 files changed, 78 insertions, 4 deletions
diff --git a/ext/opencv/gstfacedetect.cpp b/ext/opencv/gstfacedetect.cpp
index c7cb4d538..1b0d2d474 100644
--- a/ext/opencv/gstfacedetect.cpp
+++ b/ext/opencv/gstfacedetect.cpp
@@ -94,6 +94,8 @@ GST_DEBUG_CATEGORY_STATIC (gst_face_detect_debug);
#define DEFAULT_NOSE_PROFILE "haarcascade_mcs_nose.xml"
#define DEFAULT_MOUTH_PROFILE "haarcascade_mcs_mouth.xml"
#define DEFAULT_EYES_PROFILE "haarcascade_mcs_eyepair_small.xml"
+#define DEFAULT_EAR_L_PROFILE "haarcascade_mcs_leftear.xml"
+#define DEFAULT_EAR_R_PROFILE "haarcascade_mcs_rightear.xml"
#define DEFAULT_SCALE_FACTOR 1.25
#if (CV_MAJOR_VERSION >= 4)
#define DEFAULT_FLAGS CASCADE_DO_CANNY_PRUNING
@@ -254,6 +256,8 @@ gst_face_detect_finalize (GObject * obj)
g_free (filter->nose_profile);
g_free (filter->mouth_profile);
g_free (filter->eyes_profile);
+ g_free (filter->ear_l_profile);
+ g_free (filter->ear_r_profile);
if (filter->cvFaceDetect)
delete (filter->cvFaceDetect);
@@ -263,6 +267,10 @@ gst_face_detect_finalize (GObject * obj)
delete (filter->cvMouthDetect);
if (filter->cvEyesDetect)
delete (filter->cvEyesDetect);
+ if (filter->cvEarLDetect)
+ delete (filter->cvEarLDetect);
+ if (filter->cvEarRDetect)
+ delete (filter->cvEarRDetect);
G_OBJECT_CLASS (gst_face_detect_parent_class)->finalize (obj);
}
@@ -374,6 +382,8 @@ gst_face_detect_init (GstFaceDetect * filter)
filter->nose_profile = g_strconcat (haar_path, DEFAULT_NOSE_PROFILE, NULL);
filter->mouth_profile = g_strconcat (haar_path, DEFAULT_MOUTH_PROFILE, NULL);
filter->eyes_profile = g_strconcat (haar_path, DEFAULT_EYES_PROFILE, NULL);
+ filter->ear_r_profile = g_strconcat (haar_path, DEFAULT_EAR_R_PROFILE, NULL);
+ filter->ear_l_profile = g_strconcat (haar_path, DEFAULT_EAR_L_PROFILE, NULL);
filter->display = TRUE;
filter->face_detected = FALSE;
filter->scale_factor = DEFAULT_SCALE_FACTOR;
@@ -390,6 +400,10 @@ gst_face_detect_init (GstFaceDetect * filter)
gst_face_detect_load_profile (filter, filter->mouth_profile);
filter->cvEyesDetect =
gst_face_detect_load_profile (filter, filter->eyes_profile);
+ filter->cvEarLDetect =
+ gst_face_detect_load_profile (filter, filter->ear_l_profile);
+ filter->cvEarRDetect =
+ gst_face_detect_load_profile (filter, filter->ear_r_profile);
gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER_CAST (filter),
TRUE);
@@ -593,6 +607,8 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
vector < Rect > mouth;
vector < Rect > nose;
vector < Rect > eyes;
+ vector < Rect > r_ears;
+ vector < Rect > l_ears;
gboolean post_msg = FALSE;
cvtColor (img, filter->cvGray, COLOR_RGB2GRAY);
@@ -646,8 +662,10 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
guint rnx = 0, rny = 0, rnw, rnh;
guint rmx = 0, rmy = 0, rmw, rmh;
guint rex = 0, rey = 0, rew, reh;
+ guint relx = 0, rely = 0, relw, relh;
+ guint rerx = 0, rery = 0, rerw, rerh;
guint rhh = r.height / 2;
- gboolean have_nose, have_mouth, have_eyes;
+ gboolean have_nose, have_mouth, have_eyes, have_l_ears, have_r_ears;
/* detect face features */
@@ -687,11 +705,35 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
have_eyes = FALSE;
}
+ if (filter->cvEarLDetect) {
+ relx = r.x;
+ rely = r.y;
+ relw = r.width;
+ relh = rhh;
+ gst_face_detect_run_detector (filter, filter->cvEarLDetect, mw, mh,
+ Rect (relx, rely, relw, relh), l_ears);
+ have_l_ears = !l_ears.empty ();
+ } else {
+ have_l_ears = FALSE;
+ }
+
+ if (filter->cvEarRDetect) {
+ rerx = r.x;
+ rery = r.y;
+ rerw = r.width;
+ rerh = rhh;
+ gst_face_detect_run_detector (filter, filter->cvEarRDetect, mw, mh,
+ Rect (rerx, rery, rerw, rerh), r_ears);
+ have_r_ears = !r_ears.empty ();
+ } else {
+ have_r_ears = FALSE;
+ }
+
GST_LOG_OBJECT (filter,
"%2d/%2" G_GSIZE_FORMAT
- ": x,y = %4u,%4u: w.h = %4u,%4u : features(e,n,m) = %d,%d,%d", i,
- faces.size (), r.x, r.y, r.width, r.height, have_eyes, have_nose,
- have_mouth);
+ ": x,y = %4u,%4u: w.h = %4u,%4u : features(e,n,m) = %d,%d,%d,%d,%d",
+ i, faces.size (), r.x, r.y, r.width, r.height, have_eyes, have_nose,
+ have_mouth, have_r_ears, have_l_ears);
if (post_msg) {
s = gst_structure_new ("face",
"x", G_TYPE_UINT, r.x,
@@ -704,6 +746,10 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
structure_and_message (mouth, "mouth", rmx, rmy, filter, s);
if (have_eyes)
structure_and_message (eyes, "eyes", rex, rey, filter, s);
+ if (have_l_ears)
+ structure_and_message (l_ears, "left ears", relx, rely, filter, s);
+ if (have_r_ears)
+ structure_and_message (r_ears, "right ears", rerx, rery, filter, s);
g_value_init (&facedata, GST_TYPE_STRUCTURE);
g_value_take_boxed (&facedata, s);
@@ -761,6 +807,30 @@ gst_face_detect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
axes.height = h;
ellipse (img, center, axes, 0, 0, 360, Scalar (cr, cg, cb), 1, 8, 0);
}
+ if (have_r_ears) {
+ Rect sr = r_ears[0];
+
+ w = sr.width / 2;
+ h = sr.height / 2;
+ center.x = cvRound ((rerx + sr.x + w));
+ center.y = cvRound ((rery + sr.y + h));
+ axes.width = w * 1.25; /* tweak for ears form */
+ axes.height = h;
+ ellipse (mtxOrg, center, axes, 0, 0, 360, Scalar (cr, cg, cb), 1, 8,
+ 0);
+ }
+ if (have_l_ears) {
+ Rect sr = l_ears[0];
+
+ w = sr.width / 2;
+ h = sr.height / 2;
+ center.x = cvRound ((relx + sr.x + w));
+ center.y = cvRound ((rely + sr.y + h));
+ axes.width = w * 1.25; /* tweak for ears form */
+ axes.height = h;
+ ellipse (mtxOrg, center, axes, 0, 0, 360, Scalar (cr, cg, cb), 1, 8,
+ 0);
+ }
}
gst_buffer_add_video_region_of_interest_meta (buf, "face",
(guint) r.x, (guint) r.y, (guint) r.width, (guint) r.height);
diff --git a/ext/opencv/gstfacedetect.h b/ext/opencv/gstfacedetect.h
index e718844ce..68c159dd7 100644
--- a/ext/opencv/gstfacedetect.h
+++ b/ext/opencv/gstfacedetect.h
@@ -95,6 +95,8 @@ struct _GstFaceDetect
gchar *nose_profile;
gchar *mouth_profile;
gchar *eyes_profile;
+ gchar *ear_l_profile;
+ gchar *ear_r_profile;
gdouble scale_factor;
gint min_neighbors;
gint flags;
@@ -108,6 +110,8 @@ struct _GstFaceDetect
cv::CascadeClassifier *cvNoseDetect;
cv::CascadeClassifier *cvMouthDetect;
cv::CascadeClassifier *cvEyesDetect;
+ cv::CascadeClassifier *cvEarLDetect;
+ cv::CascadeClassifier *cvEarRDetect;
};
struct _GstFaceDetectClass