From 7f55dc4bc6c93e69dd6fda7cc3247b68f91affef Mon Sep 17 00:00:00 2001 From: "Reynaldo H. Verdejo Pinochet" Date: Sun, 26 Nov 2017 17:24:56 -0800 Subject: opencv: facedetect: add right/left ear detection --- ext/opencv/gstfacedetect.cpp | 78 +++++++++++++++++++++++++++++++++++++++++--- ext/opencv/gstfacedetect.h | 4 +++ 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 -- cgit v1.2.3