From e17b555efde96f5c4a8df48545cd61f2823c7c34 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Wed, 19 May 2010 20:11:39 -0300 Subject: [PATCH] Adds new element cvsobel --- ext/opencv/basicfilters/Makefile.am | 6 +- ext/opencv/basicfilters/gstcvsobel.c | 281 +++++++++++++++++++++++++++ ext/opencv/basicfilters/gstcvsobel.h | 88 +++++++++ ext/opencv/gstopencv.c | 5 +- ext/opencv/gstopencvutils.c | 7 +- 5 files changed, 382 insertions(+), 5 deletions(-) create mode 100644 ext/opencv/basicfilters/gstcvsobel.c create mode 100644 ext/opencv/basicfilters/gstcvsobel.h diff --git a/ext/opencv/basicfilters/Makefile.am b/ext/opencv/basicfilters/Makefile.am index 4980beb9a5..e71c6684c0 100644 --- a/ext/opencv/basicfilters/Makefile.am +++ b/ext/opencv/basicfilters/Makefile.am @@ -5,7 +5,8 @@ libgstbasicfilters_la_SOURCES = gstcvsmooth.c \ gstcvdilateerode.c \ gstcvdilate.c \ gstcvequalizehist.c \ - gstcverode.c + gstcverode.c \ + gstcvsobel.c # flags used to compile this pyramidsegment # add other _CFLAGS and _LIBS as needed @@ -18,4 +19,5 @@ noinst_HEADERS = gstcvsmooth.h \ gstcvdilateerode.h \ gstcvdilate.h \ gstcvequalizehist.h \ - gstcverode.h + gstcverode.h \ + gstcvsobel.c diff --git a/ext/opencv/basicfilters/gstcvsobel.c b/ext/opencv/basicfilters/gstcvsobel.c new file mode 100644 index 0000000000..dcbf01bcb8 --- /dev/null +++ b/ext/opencv/basicfilters/gstcvsobel.c @@ -0,0 +1,281 @@ +/* + * GStreamer + * Copyright (C) 2010 Thiago Santos + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "gstcvsobel.h" + +GST_DEBUG_CATEGORY_STATIC (gst_cv_sobel_debug); +#define GST_CAT_DEFAULT gst_cv_sobel_debug + +static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-gray, depth=(int)8, bpp=(int)8") + ); + +static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + GST_STATIC_CAPS + ("video/x-raw-gray, depth=(int)16, bpp=(int)16, endianness=(int)4321") + ); + +/* Filter signals and args */ +enum +{ + /* FILL ME */ + LAST_SIGNAL +}; +enum +{ + PROP_0, + PROP_X_ORDER, + PROP_Y_ORDER, + PROP_APERTURE_SIZE +}; + +#define DEFAULT_X_ORDER 1 +#define DEFAULT_Y_ORDER 0 +#define DEFAULT_APERTURE_SIZE 3 + +GST_BOILERPLATE (GstCvSobel, gst_cv_sobel, GstOpencvBaseTransform, + GST_TYPE_OPENCV_BASE_TRANSFORM); + +static void gst_cv_sobel_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_cv_sobel_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GstCaps *gst_cv_sobel_transform_caps (GstBaseTransform * trans, + GstPadDirection dir, GstCaps * caps); + +static GstFlowReturn gst_cv_sobel_transform (GstOpencvBaseTransform * filter, + GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); + +/* Clean up */ +static void +gst_cv_sobel_finalize (GObject * obj) +{ + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +/* GObject vmethod implementations */ + +static void +gst_cv_sobel_base_init (gpointer gclass) +{ + GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + + 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)); + + gst_element_class_set_details_simple (element_class, + "cvsobel", + "Transform/Effect/Video", + "Applies cvSobel OpenCV function to the image", + "Thiago Santos"); +} + +/* initialize the cvsobel's class */ +static void +gst_cv_sobel_class_init (GstCvSobelClass * klass) +{ + GObjectClass *gobject_class; + GstBaseTransformClass *gstbasetransform_class; + GstOpencvBaseTransformClass *gstopencvbasefilter_class; + GstElementClass *gstelement_class; + + gobject_class = (GObjectClass *) klass; + gstelement_class = (GstElementClass *) klass; + gstbasetransform_class = (GstBaseTransformClass *) klass; + gstopencvbasefilter_class = (GstOpencvBaseTransformClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_cv_sobel_finalize); + gobject_class->set_property = gst_cv_sobel_set_property; + gobject_class->get_property = gst_cv_sobel_get_property; + + gstbasetransform_class->transform_caps = gst_cv_sobel_transform_caps; + + gstopencvbasefilter_class->cv_trans_func = gst_cv_sobel_transform; + + g_object_class_install_property (gobject_class, PROP_X_ORDER, + g_param_spec_int ("x-order", "x order", + "Order of the derivative x", -1, G_MAXINT, + DEFAULT_X_ORDER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_Y_ORDER, + g_param_spec_int ("y-order", "y order", + "Order of the derivative y", -1, G_MAXINT, + DEFAULT_Y_ORDER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_APERTURE_SIZE, + g_param_spec_int ("aperture-size", "aperture size", + "Size of the extended Sobel Kernel (1, 3, 5 or 7)", 1, 7, + DEFAULT_APERTURE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_cv_sobel_init (GstCvSobel * filter, GstCvSobelClass * gclass) +{ + filter->x_order = DEFAULT_X_ORDER; + filter->y_order = DEFAULT_Y_ORDER; + filter->aperture_size = DEFAULT_APERTURE_SIZE; + + gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), FALSE); +} + +static GstCaps * +gst_cv_sobel_transform_caps (GstBaseTransform * trans, GstPadDirection dir, + GstCaps * caps) +{ + GstCaps *output = NULL; + GstStructure *structure; + gint i; + + output = gst_caps_copy (caps); + + /* we accept anything from the template caps for either side */ + switch (dir) { + case GST_PAD_SINK: + for (i = 0; i < gst_caps_get_size (output); i++) { + structure = gst_caps_get_structure (output, i); + gst_structure_set (structure, + "depth", G_TYPE_INT, 16, + "bpp", G_TYPE_INT, 16, "endianness", G_TYPE_INT, 4321, NULL); + } + break; + case GST_PAD_SRC: + for (i = 0; i < gst_caps_get_size (output); i++) { + structure = gst_caps_get_structure (output, i); + gst_structure_set (structure, + "depth", G_TYPE_INT, 8, "bpp", G_TYPE_INT, 8, NULL); + gst_structure_remove_field (structure, "endianness"); + } + break; + default: + gst_caps_unref (output); + output = NULL; + g_assert_not_reached (); + break; + } + + return output; +} + +static void +gst_cv_sobel_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstCvSobel *filter = GST_CV_SOBEL (object); + + switch (prop_id) { + case PROP_X_ORDER: + filter->x_order = g_value_get_int (value); + break; + case PROP_Y_ORDER: + filter->y_order = g_value_get_int (value); + break; + case PROP_APERTURE_SIZE:{ + gint as = g_value_get_int (value); + + if (as % 2 != 1) { + GST_WARNING_OBJECT (filter, "Invalid value %d for aperture size", as); + } else + filter->aperture_size = g_value_get_int (value); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_cv_sobel_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstCvSobel *filter = GST_CV_SOBEL (object); + + switch (prop_id) { + case PROP_X_ORDER: + g_value_set_int (value, filter->x_order); + break; + case PROP_Y_ORDER: + g_value_set_int (value, filter->y_order); + break; + case PROP_APERTURE_SIZE: + g_value_set_int (value, filter->aperture_size); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GstFlowReturn +gst_cv_sobel_transform (GstOpencvBaseTransform * base, GstBuffer * buf, + IplImage * img, GstBuffer * outbuf, IplImage * outimg) +{ + GstCvSobel *filter = GST_CV_SOBEL (base); + + cvSobel (img, outimg, filter->x_order, filter->y_order, + filter->aperture_size); + + return GST_FLOW_OK; +} + +gboolean +gst_cv_sobel_plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (gst_cv_sobel_debug, "cvsobel", 0, "cvsobel"); + + return gst_element_register (plugin, "cvsobel", GST_RANK_NONE, + GST_TYPE_CV_SOBEL); +} diff --git a/ext/opencv/basicfilters/gstcvsobel.h b/ext/opencv/basicfilters/gstcvsobel.h new file mode 100644 index 0000000000..d9effd658e --- /dev/null +++ b/ext/opencv/basicfilters/gstcvsobel.h @@ -0,0 +1,88 @@ +/* + * GStreamer + * Copyright (C) 2010 Thiago Santos + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_CV_SOBEL_H__ +#define __GST_CV_SOBEL_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define GST_TYPE_CV_SOBEL \ + (gst_cv_sobel_get_type()) +#define GST_CV_SOBEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CV_SOBEL,GstCvSobel)) +#define GST_CV_SOBEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CV_SOBEL,GstCvSobelClass)) +#define GST_IS_CV_SOBEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CV_SOBEL)) +#define GST_IS_CV_SOBEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CV_SOBEL)) + +typedef struct _GstCvSobel GstCvSobel; +typedef struct _GstCvSobelClass GstCvSobelClass; + +struct _GstCvSobel +{ + GstOpencvBaseTransform element; + + gint x_order; + gint y_order; + gint aperture_size; +}; + +struct _GstCvSobelClass +{ + GstOpencvBaseTransformClass parent_class; +}; + +GType gst_cv_sobel_get_type (void); + +gboolean gst_cv_sobel_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif /* __GST_CV_SOBEL_H__ */ diff --git a/ext/opencv/gstopencv.c b/ext/opencv/gstopencv.c index 77653a8a70..42fb04d574 100644 --- a/ext/opencv/gstopencv.c +++ b/ext/opencv/gstopencv.c @@ -27,6 +27,7 @@ #include "gstcvequalizehist.h" #include "gstcverode.h" #include "gstcvsmooth.h" +#include "gstcvsobel.h" #include "gstedgedetect.h" #include "gstfaceblur.h" #include "gstfacedetect.h" @@ -37,7 +38,6 @@ static gboolean plugin_init (GstPlugin * plugin) { - if (!gst_cv_dilate_plugin_init (plugin)) return FALSE; @@ -50,6 +50,9 @@ plugin_init (GstPlugin * plugin) if (!gst_cv_smooth_plugin_init (plugin)) return FALSE; + if (!gst_cv_sobel_plugin_init (plugin)) + return FALSE; + if (!gst_edgedetect_plugin_init (plugin)) return FALSE; diff --git a/ext/opencv/gstopencvutils.c b/ext/opencv/gstopencvutils.c index 0b58397395..2848141386 100644 --- a/ext/opencv/gstopencvutils.c +++ b/ext/opencv/gstopencvutils.c @@ -53,6 +53,8 @@ gst_opencv_get_ipl_depth_and_channels (GstStructure * structure, if (depth / *channels == 8) { /* TODO signdness? */ *ipldepth = IPL_DEPTH_8U; + } else if (depth / *channels == 16) { + *ipldepth = IPL_DEPTH_16U; } else { g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_NEGOTIATION, "Unsupported depth/channels %d/%d", depth, *channels); @@ -86,6 +88,7 @@ gboolean gst_opencv_parse_iplimage_params_from_caps (GstCaps * caps, gint * width, gint * height, gint * ipldepth, gint * channels, GError ** err) { - return gst_opencv_parse_iplimage_params_from_structure ( - gst_caps_get_structure (caps, 0), width, height, ipldepth, channels, err); + return + gst_opencv_parse_iplimage_params_from_structure (gst_caps_get_structure + (caps, 0), width, height, ipldepth, channels, err); }