diff options
Diffstat (limited to 'ext/opencv')
-rw-r--r-- | ext/opencv/Makefile.am | 7 | ||||
-rw-r--r-- | ext/opencv/gsthanddetect.c | 220 | ||||
-rw-r--r-- | ext/opencv/gsthanddetect.h | 22 | ||||
-rw-r--r-- | ext/opencv/gstopencv.c | 4 |
4 files changed, 74 insertions, 179 deletions
diff --git a/ext/opencv/Makefile.am b/ext/opencv/Makefile.am index c02037b22..4bcc78ed2 100644 --- a/ext/opencv/Makefile.am +++ b/ext/opencv/Makefile.am @@ -14,6 +14,7 @@ libgstopencv_la_SOURCES = gstopencv.c \ gstedgedetect.c \ gstfaceblur.c \ gstfacedetect.c \ + gsthanddetect.c \ gstpyramidsegment.c \ gsttemplatematch.c \ gsttextoverlay.c \ @@ -50,9 +51,15 @@ noinst_HEADERS = gstopencvvideofilter.h gstopencvutils.h \ gstedgedetect.h \ gstfaceblur.h \ gstfacedetect.h \ + gsthanddetect.h \ gstpyramidsegment.h \ gsttemplatematch.h \ gsttextoverlay.h \ gstmotioncells.h \ motioncells_wrapper.h \ MotionCells.h + +opencv_haarcascadesdir = $(datadir)/gstreamer-$(GST_API_VERSION)/opencv_haarcascades +opencv_haarcascades_DATA = fist.xml palm.xml + +EXTRA_DIST = $(opencv_haarcascades_DATA) diff --git a/ext/opencv/gsthanddetect.c b/ext/opencv/gsthanddetect.c index 223a18595..57885c7ba 100644 --- a/ext/opencv/gsthanddetect.c +++ b/ext/opencv/gsthanddetect.c @@ -1,6 +1,7 @@ /* * GStreamer hand gesture detection plugins * Copyright (C) 2012 Andol Li <<andol@andol.info>> + * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -49,8 +50,8 @@ * <refsect2> * <title>Example launch line</title> * |[ - * gst-launch autovideosrc ! ffmpegcolorspace ! "video/x-raw-rgb, width=320, height=240" ! \ - videoscale ! handdetect ! ffmpegcolorspace ! xvimagesink + * gst-launch autovideosrc ! videoconvert ! "video/x-raw, formt=RGB, width=320, height=240" ! \ + videoscale ! handdetect ! videoconvert ! xvimagesink * ]| * </refsect2> */ @@ -58,23 +59,18 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif -/* interfaces */ -#include <gst/interfaces/navigation.h> + /* element header */ #include "gsthanddetect.h" -/* gst */ -#include <gst/gst.h> -#include <gst/video/video.h> #include "gstopencvutils.h" -/* debugging */ -#include <gst/gstinfo.h> GST_DEBUG_CATEGORY_STATIC (gst_handdetect_debug); #define GST_CAT_DEFAULT gst_handdetect_debug /* define HAAR files */ -#define HAAR_FILE_FIST "/usr/local/share/opencv/haarcascades/fist.xml" -#define HAAR_FILE_PALM "/usr/local/share/opencv/haarcascades/palm.xml" +#define HAAR_CASCADES_DIR GST_DATADIR "/gstreamer-"GST_API_VERSION"/opencv_haarcascades/" +#define HAAR_FILE_FIST HAAR_CASCADES_DIR "fist.xml" +#define HAAR_FILE_PALM HAAR_CASCADES_DIR "palm.xml" /* Filter signals and args */ enum @@ -99,12 +95,12 @@ enum static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")) ); static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB) + GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGB")) ); static void gst_handdetect_set_property (GObject * object, guint prop_id, @@ -119,60 +115,22 @@ static GstFlowReturn gst_handdetect_transform_ip (GstOpencvVideoFilter * static void gst_handdetect_load_profile (GstHanddetect * filter); -static void gst_handdetect_init_interfaces (GType type); -static void -gst_handdetect_implements_interface_init (GstImplementsInterfaceClass * klass); -static void gst_handdetect_navigation_interface_init (gpointer g_iface, - gpointer iface_data); -static gboolean gst_handdetect_interface_supported (GstImplementsInterface * - iface, GType type); +static void gst_handdetect_navigation_interface_init (GstNavigationInterface * + iface); static void gst_handdetect_navigation_send_event (GstNavigation * navigation, GstStructure * structure); -static gboolean gst_handdetect_handle_pad_event (GstPad * pad, - GstEvent * event); -GST_BOILERPLATE_FULL (GstHanddetect, gst_handdetect, GstOpencvVideoFilter, - GST_TYPE_OPENCV_VIDEO_FILTER, gst_handdetect_init_interfaces); +G_DEFINE_TYPE_WITH_CODE (GstHanddetect, gst_handdetect, + GST_TYPE_OPENCV_VIDEO_FILTER, + G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, + gst_handdetect_navigation_interface_init);); static void -gst_handdetect_init_interfaces (GType type) +gst_handdetect_navigation_interface_init (GstNavigationInterface * iface) { - static const GInterfaceInfo iface_info = { - (GInterfaceInitFunc) gst_handdetect_implements_interface_init, - NULL, - NULL, - }; - g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, - &iface_info); - static const GInterfaceInfo navigation_info = { - (GInterfaceInitFunc) gst_handdetect_navigation_interface_init, - NULL, - NULL, - }; - g_type_add_interface_static (type, GST_TYPE_NAVIGATION, &navigation_info); -} - -static void -gst_handdetect_navigation_interface_init (gpointer g_iface, gpointer iface_data) -{ - GstNavigationInterface *iface = (GstNavigationInterface *) g_iface; iface->send_event = gst_handdetect_navigation_send_event; } -static gboolean -gst_handdetect_interface_supported (GstImplementsInterface * iface, GType type) -{ - if (type == GST_TYPE_NAVIGATION) - return TRUE; - return FALSE; -} - -static void -gst_handdetect_implements_interface_init (GstImplementsInterfaceClass * klass) -{ - klass->supported = gst_handdetect_interface_supported; -} - /* FIXME: this function used to parse the region of interests coordinates * sending from applications when the hand gestures reach the defined regions of interests, * at this moment this function is not doing anything significantly @@ -193,60 +151,9 @@ gst_handdetect_navigation_send_event (GstNavigation * navigation, } } -/* handle element pad event */ -/* no PRACTICAL USE at the moment - * this function is used to debug the fist-move/palm-move event - * will CHANGE in the future - */ -static gboolean -gst_handdetect_handle_pad_event (GstPad * pad, GstEvent * event) -{ - const GstStructure *s = gst_event_get_structure (event); - const gchar *name = gst_structure_get_string (s, "event"); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - break; - case GST_EVENT_NAVIGATION:{ - if (g_str_equal (name, "fist-move")) { - GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), - "Fist-move event\n "); - uint x, y; - gst_structure_get_uint (s, "x", &x); - gst_structure_get_uint (s, "y", &y); - GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), - "Fist Pos:[%d, %d]\n", x, y); - } else if (g_str_equal (name, "palm-move")) { - GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), - "Palm-move event\n "); - uint x, y; - gst_structure_get_uint (s, "x", &x); - gst_structure_get_uint (s, "y", &y); - GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), - "Palm Pos:[%d, %d]\n", x, y); - } else if (g_str_equal (name, "mouse-move")) { - gdouble x, y; - gst_structure_get_double (s, "pointer_x", &x); - gst_structure_get_double (s, "pointer_y", &y); - GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), - "Mouse-move [%f, %f]\n", x, y); - } else if (g_str_equal (name, "mouse-button-press")) { - GST_DEBUG ("Mouse botton press\n"); - } else if (g_str_equal (name, "mouse-button-release")) { - GST_DEBUG_OBJECT (GST_HANDDETECT (gst_pad_get_parent (pad)), - "Mouse button release\n"); - } - break; - } - default: - break; - } - return gst_pad_event_default (pad, event); -} - /* clean opencv images and parameters */ static void -gst_handdetect_finalise (GObject * obj) +gst_handdetect_finalize (GObject * obj) { GstHanddetect *filter = GST_HANDDETECT (obj); @@ -257,23 +164,7 @@ gst_handdetect_finalise (GObject * obj) g_free (filter->profile_fist); g_free (filter->profile_palm); - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -/* GObject vmethod implementations */ -static void -gst_handdetect_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_set_details_simple (element_class, - "hand detect", - "Filter/Effect/Video", - "Performs hand gesture detection on videos, providing detected hand positions via bus message and navigation event, and deals with hand gesture events", - "Andol Li <<andol@andol.info>>"); - - gst_element_class_add_static_pad_template (element_class, &src_factory); - gst_element_class_add_static_pad_template (element_class, &sink_factory); + G_OBJECT_CLASS (gst_handdetect_parent_class)->finalize (obj); } /* initialise the HANDDETECT class */ @@ -283,13 +174,14 @@ gst_handdetect_class_init (GstHanddetectClass * klass) GObjectClass *gobject_class; GstOpencvVideoFilterClass *gstopencvbasefilter_class; + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); gobject_class = (GObjectClass *) klass; gstopencvbasefilter_class = (GstOpencvVideoFilterClass *) klass; gstopencvbasefilter_class->cv_trans_ip_func = gst_handdetect_transform_ip; gstopencvbasefilter_class->cv_set_caps = gst_handdetect_set_caps; - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_handdetect_finalise); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_handdetect_finalize); gobject_class->set_property = gst_handdetect_set_property; gobject_class->get_property = gst_handdetect_get_property; @@ -342,6 +234,18 @@ gst_handdetect_class_init (GstHanddetectClass * klass) "HEIGHT of left-top pointer in region of interest \nGestures in the defined region of interest will emit messages", 0, UINT_MAX, 0, G_PARAM_READWRITE) ); + + gst_element_class_set_static_metadata (element_class, + "handdetect", + "Filter/Effect/Video", + "Performs hand gesture detection on videos, providing detected hand positions via bus message and navigation event, and deals with hand gesture events", + "Andol Li <andol@andol.info>"); + + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&src_factory)); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&sink_factory)); + } /* initialise the new element @@ -350,13 +254,8 @@ gst_handdetect_class_init (GstHanddetectClass * klass) * initialise instance structure */ static void -gst_handdetect_init (GstHanddetect * filter, GstHanddetectClass * gclass) +gst_handdetect_init (GstHanddetect * filter) { - GstBaseTransform *trans = GST_BASE_TRANSFORM_CAST (filter); - - gst_pad_set_event_function (trans->srcpad, - GST_DEBUG_FUNCPTR (gst_handdetect_handle_pad_event)); - filter->profile_fist = g_strdup (HAAR_FILE_FIST); filter->profile_palm = g_strdup (HAAR_FILE_PALM); filter->roi_x = 0; @@ -481,13 +380,17 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, GstBuffer * buffer, IplImage * img) { GstHanddetect *filter = GST_HANDDETECT (transform); + GstMapInfo info; CvSeq *hands; CvRect *r; GstStructure *s; GstMessage *m; int i; - filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buffer); + buffer = gst_buffer_make_writable (buffer); + gst_buffer_map (buffer, &info, GST_MAP_READWRITE); + + filter->cvImage->imageData = (char *) info.data; /* 320 x 240 is with the best detect accuracy, if not, give info */ if (filter->cvImage->width != 320 || filter->cvImage->height != 240) GST_INFO_OBJECT (filter, @@ -511,6 +414,9 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, /* if FIST gesture detected */ if (hands && hands->total > 0) { + int min_distance, distance; + CvRect temp_r; + CvPoint c; /* set frame buffer writable */ if (filter->display) { buffer = gst_buffer_make_writable (buffer); @@ -522,15 +428,15 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, * best_r => best hand in this frame */ /* set min_distance for init comparison */ - int min_distance = filter->cvImage->width + filter->cvImage->height; + min_distance = filter->cvImage->width + filter->cvImage->height; /* Init filter->prev_r */ - CvRect temp_r = cvRect (0, 0, 0, 0); + temp_r = cvRect (0, 0, 0, 0); if (filter->prev_r == NULL) filter->prev_r = &temp_r; /* Get the best FIST gesture */ for (i = 0; i < (hands ? hands->total : 0); i++) { r = (CvRect *) cvGetSeqElem (hands, i); - int distance = (int) sqrt (pow ((r->x - filter->prev_r->x), + distance = (int) sqrt (pow ((r->x - filter->prev_r->x), 2) + pow ((r->y - filter->prev_r->y), 2)); if (distance <= min_distance) { min_distance = distance; @@ -541,8 +447,7 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, filter->prev_r = (CvRect *) filter->best_r; /* send msg to app/bus if the detected gesture falls in the region of interest */ /* get center point of gesture */ - CvPoint c = - cvPoint (filter->best_r->x + filter->best_r->width / 2, + c = cvPoint (filter->best_r->x + filter->best_r->width / 2, filter->best_r->y + filter->best_r->height / 2); /* send message: * if the center point is in the region of interest, OR, @@ -602,6 +507,9 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, ); /* if PALM detected */ if (hands && hands->total > 0) { + int min_distance, distance; + CvRect temp_r; + CvPoint c; /* set frame buffer writable */ if (filter->display) { buffer = gst_buffer_make_writable (buffer); @@ -613,15 +521,15 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, * best_r => best hand in this frame */ /* suppose a min_distance for init comparison */ - int min_distance = filter->cvImage->width + filter->cvImage->height; + min_distance = filter->cvImage->width + filter->cvImage->height; /* Init filter->prev_r */ - CvRect temp_r = cvRect (0, 0, 0, 0); + temp_r = cvRect (0, 0, 0, 0); if (filter->prev_r == NULL) filter->prev_r = &temp_r; /* Get the best PALM gesture */ for (i = 0; i < (hands ? hands->total : 0); i++) { r = (CvRect *) cvGetSeqElem (hands, i); - int distance = (int) sqrt (pow ((r->x - filter->prev_r->x), + distance = (int) sqrt (pow ((r->x - filter->prev_r->x), 2) + pow ((r->y - filter->prev_r->y), 2)); if (distance <= min_distance) { min_distance = distance; @@ -633,8 +541,7 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, /* send msg to app/bus if the detected gesture falls in the region of interest */ /* get center point of gesture */ - CvPoint c = - cvPoint (filter->best_r->x + filter->best_r->width / 2, + c = cvPoint (filter->best_r->x + filter->best_r->width / 2, filter->best_r->y + filter->best_r->height / 2); /* send message: * if the center point is in the region of interest, OR, @@ -700,7 +607,7 @@ gst_handdetect_transform_ip (GstOpencvVideoFilter * transform, } } } - + gst_buffer_unmap (buffer, &info); /* Push out the incoming buffer */ return GST_FLOW_OK; } @@ -731,7 +638,7 @@ gst_handdetect_load_profile (GstHanddetect * filter) * Initialize the plug-in itself * Register the element factories and other features */ -static gboolean +gboolean gst_handdetect_plugin_init (GstPlugin * plugin) { GST_DEBUG_CATEGORY_INIT (gst_handdetect_debug, @@ -741,22 +648,3 @@ gst_handdetect_plugin_init (GstPlugin * plugin) return gst_element_register (plugin, "handdetect", GST_RANK_NONE, GST_TYPE_HANDDETECT); } - -/* PACKAGE: this is usually set by autotools depending on some _INIT macro - * in configure.ac and then written into and defined in config.h, but we can - * just set it ourselves here in case someone doesn't use autotools to - * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined. - */ -#ifndef PACKAGE -#define PACKAGE "gst_handdetect" -#endif - -/* - * Gstreamer looks for this structure to register handdetect - */ -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "handdetect", - "Detect hand gestures for media operations", - gst_handdetect_plugin_init, VERSION, "LGPL", "GStreamer", - "http://gstreamer.net/") diff --git a/ext/opencv/gsthanddetect.h b/ext/opencv/gsthanddetect.h index 1d4a6831d..9fb69a6a1 100644 --- a/ext/opencv/gsthanddetect.h +++ b/ext/opencv/gsthanddetect.h @@ -1,8 +1,7 @@ /* * GStreamer - * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org> - * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net> * Copyright (C) 2012 andol li <<andol@andol.info>> + * Copyright (c) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -46,20 +45,15 @@ #ifndef __GST_HANDDETECT_H__ #define __GST_HANDDETECT_H__ -#ifndef VERSION -#define VERSION "0.10.36" /* for GST_PLUGIN_DEFINE use */ -#endif - -#include <math.h> -#include <string.h> -#include <stdlib.h> #include <gst/gst.h> -#include <gst/video/gstvideofilter.h> +#include <gst/video/video.h> +#include <gst/video/navigation.h> + #include "gstopencvvideofilter.h" /* opencv */ -#include <opencv/cv.h> -#include <opencv/cxcore.h> -#include <opencv/highgui.h> +#include <cv.h> +#include <cxcore.h> +#include <highgui.h> #if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) #include <opencv2/objdetect/objdetect.hpp> #endif @@ -113,5 +107,7 @@ struct _GstHanddetectClass GType gst_handdetect_get_type (void); +gboolean gst_handdetect_plugin_init (GstPlugin * plugin); + G_END_DECLS #endif /* __GST_HANDDETECT_H__ */ diff --git a/ext/opencv/gstopencv.c b/ext/opencv/gstopencv.c index afcdb41ab..289192240 100644 --- a/ext/opencv/gstopencv.c +++ b/ext/opencv/gstopencv.c @@ -36,6 +36,7 @@ #include "gstpyramidsegment.h" #include "gsttemplatematch.h" #include "gsttextoverlay.h" +#include "gsthanddetect.h" static gboolean plugin_init (GstPlugin * plugin) @@ -79,6 +80,9 @@ plugin_init (GstPlugin * plugin) if (!gst_opencv_text_overlay_plugin_init (plugin)) return FALSE; + if (!gst_handdetect_plugin_init (plugin)) + return FALSE; + return TRUE; } |