From 4c03c980ceaf8738f9b4f11485bb328157fcc239 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 24 May 2010 19:28:59 -0300 Subject: [PATCH] cvlaplace: adds new cvlaplace element Adds new cvlaplace element. Also adds a new opencvbasetransform function to be overriden by children classes: the cv_set_caps, it allows children classes to know what are they going to handle and prepare properly. --- ext/opencv/basicfilters/Makefile.am | 4 +- ext/opencv/basicfilters/gstcvlaplace.c | 296 +++++++++++++++++++++++++++++++++ ext/opencv/basicfilters/gstcvlaplace.h | 88 ++++++++++ ext/opencv/gstopencv.c | 4 + ext/opencv/gstopencvbasetrans.c | 8 + ext/opencv/gstopencvbasetrans.h | 7 + 6 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 ext/opencv/basicfilters/gstcvlaplace.c create mode 100644 ext/opencv/basicfilters/gstcvlaplace.h diff --git a/ext/opencv/basicfilters/Makefile.am b/ext/opencv/basicfilters/Makefile.am index e71c668..45a5dc4 100644 --- a/ext/opencv/basicfilters/Makefile.am +++ b/ext/opencv/basicfilters/Makefile.am @@ -5,6 +5,7 @@ libgstbasicfilters_la_SOURCES = gstcvsmooth.c \ gstcvdilateerode.c \ gstcvdilate.c \ gstcvequalizehist.c \ + gstcvlaplace.c \ gstcverode.c \ gstcvsobel.c @@ -20,4 +21,5 @@ noinst_HEADERS = gstcvsmooth.h \ gstcvdilate.h \ gstcvequalizehist.h \ gstcverode.h \ - gstcvsobel.c + gstcvlaplace.h \ + gstcvsobel.h diff --git a/ext/opencv/basicfilters/gstcvlaplace.c b/ext/opencv/basicfilters/gstcvlaplace.c new file mode 100644 index 0000000..31cb4da --- /dev/null +++ b/ext/opencv/basicfilters/gstcvlaplace.c @@ -0,0 +1,296 @@ +/* + * 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 "gstcvlaplace.h" + +GST_DEBUG_CATEGORY_STATIC (gst_cv_laplace_debug); +#define GST_CAT_DEFAULT gst_cv_laplace_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_APERTURE_SIZE +}; + +#define DEFAULT_APERTURE_SIZE 3 + +GST_BOILERPLATE (GstCvLaplace, gst_cv_laplace, GstOpencvBaseTransform, + GST_TYPE_OPENCV_BASE_TRANSFORM); + +static void gst_cv_laplace_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_cv_laplace_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + +static GstCaps *gst_cv_laplace_transform_caps (GstBaseTransform * trans, + GstPadDirection dir, GstCaps * caps); + +static GstFlowReturn gst_cv_laplace_transform (GstOpencvBaseTransform * filter, + GstBuffer * buf, IplImage * img, GstBuffer * outbuf, IplImage * outimg); + +static gboolean gst_cv_laplace_cv_set_caps (GstOpencvBaseTransform * trans, + gint in_width, gint in_height, gint in_depth, gint in_channels, + gint out_width, gint out_height, gint out_depth, gint out_channels); + +/* Clean up */ +static void +gst_cv_laplace_finalize (GObject * obj) +{ + GstCvLaplace *filter = GST_CV_LAPLACE (obj); + + if (filter->intermediary_img) + cvReleaseImage (&filter->intermediary_img); + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +/* GObject vmethod implementations */ + +static void +gst_cv_laplace_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, + "cvlaplace", + "Transform/Effect/Video", + "Applies cvLaplace OpenCV function to the image", + "Thiago Santos"); +} + +/* initialize the cvlaplace's class */ +static void +gst_cv_laplace_class_init (GstCvLaplaceClass * 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_laplace_finalize); + gobject_class->set_property = gst_cv_laplace_set_property; + gobject_class->get_property = gst_cv_laplace_get_property; + + gstbasetransform_class->transform_caps = gst_cv_laplace_transform_caps; + + gstopencvbasefilter_class->cv_trans_func = gst_cv_laplace_transform; + gstopencvbasefilter_class->cv_set_caps = gst_cv_laplace_cv_set_caps; + + g_object_class_install_property (gobject_class, PROP_APERTURE_SIZE, + g_param_spec_int ("aperture-size", "aperture size", + "Size of the extended Laplace Kernel (1, 3, 5 or 7)", 1, 7, + DEFAULT_APERTURE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +} + +static void +gst_cv_laplace_init (GstCvLaplace * filter, GstCvLaplaceClass * gclass) +{ + filter->aperture_size = DEFAULT_APERTURE_SIZE; + + gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), FALSE); +} + +static gboolean +gst_cv_laplace_cv_set_caps (GstOpencvBaseTransform * trans, gint in_width, + gint in_height, gint in_depth, gint in_channels, gint out_width, + gint out_height, gint out_depth, gint out_channels) +{ + GstCvLaplace *filter = GST_CV_LAPLACE (trans); + gint intermediary_depth; + + /* cvLaplace needs an signed output, so we create our intermediary step + * image here */ + switch (out_depth) { + case IPL_DEPTH_16U: + intermediary_depth = IPL_DEPTH_16S; + break; + default: + GST_WARNING_OBJECT (filter, "Unsupported output depth %d", out_depth); + return FALSE; + } + + if (filter->intermediary_img) { + cvReleaseImage (&filter->intermediary_img); + } + + filter->intermediary_img = cvCreateImage (cvSize (out_width, out_height), + intermediary_depth, out_channels); + + return TRUE; +} + +static GstCaps * +gst_cv_laplace_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_laplace_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstCvLaplace *filter = GST_CV_LAPLACE (object); + + switch (prop_id) { + 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_laplace_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstCvLaplace *filter = GST_CV_LAPLACE (object); + + switch (prop_id) { + 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_laplace_transform (GstOpencvBaseTransform * base, GstBuffer * buf, + IplImage * img, GstBuffer * outbuf, IplImage * outimg) +{ + GstCvLaplace *filter = GST_CV_LAPLACE (base); + + g_assert (filter->intermediary_img); + + cvLaplace (img, filter->intermediary_img, filter->aperture_size); + cvConvertScale (filter->intermediary_img, outimg, 1, 0); + + return GST_FLOW_OK; +} + +gboolean +gst_cv_laplace_plugin_init (GstPlugin * plugin) +{ + GST_DEBUG_CATEGORY_INIT (gst_cv_laplace_debug, "cvlaplace", 0, "cvlaplace"); + + return gst_element_register (plugin, "cvlaplace", GST_RANK_NONE, + GST_TYPE_CV_LAPLACE); +} diff --git a/ext/opencv/basicfilters/gstcvlaplace.h b/ext/opencv/basicfilters/gstcvlaplace.h new file mode 100644 index 0000000..74fe3d7 --- /dev/null +++ b/ext/opencv/basicfilters/gstcvlaplace.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_LAPLACE_H__ +#define __GST_CV_LAPLACE_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/* #defines don't like whitespacey bits */ +#define GST_TYPE_CV_LAPLACE \ + (gst_cv_laplace_get_type()) +#define GST_CV_LAPLACE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CV_LAPLACE,GstCvLaplace)) +#define GST_CV_LAPLACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CV_LAPLACE,GstCvLaplaceClass)) +#define GST_IS_CV_LAPLACE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CV_LAPLACE)) +#define GST_IS_CV_LAPLACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CV_LAPLACE)) + +typedef struct _GstCvLaplace GstCvLaplace; +typedef struct _GstCvLaplaceClass GstCvLaplaceClass; + +struct _GstCvLaplace +{ + GstOpencvBaseTransform element; + + gint aperture_size; + + IplImage *intermediary_img; +}; + +struct _GstCvLaplaceClass +{ + GstOpencvBaseTransformClass parent_class; +}; + +GType gst_cv_laplace_get_type (void); + +gboolean gst_cv_laplace_plugin_init (GstPlugin * plugin); + +G_END_DECLS + +#endif /* __GST_CV_LAPLACE_H__ */ diff --git a/ext/opencv/gstopencv.c b/ext/opencv/gstopencv.c index 42fb04d..8159bd9 100644 --- a/ext/opencv/gstopencv.c +++ b/ext/opencv/gstopencv.c @@ -26,6 +26,7 @@ #include "gstcvdilate.h" #include "gstcvequalizehist.h" #include "gstcverode.h" +#include "gstcvlaplace.h" #include "gstcvsmooth.h" #include "gstcvsobel.h" #include "gstedgedetect.h" @@ -47,6 +48,9 @@ plugin_init (GstPlugin * plugin) if (!gst_cv_erode_plugin_init (plugin)) return FALSE; + if (!gst_cv_laplace_plugin_init (plugin)) + return FALSE; + if (!gst_cv_smooth_plugin_init (plugin)) return FALSE; diff --git a/ext/opencv/gstopencvbasetrans.c b/ext/opencv/gstopencvbasetrans.c index 2af72a7..f47a5dd 100644 --- a/ext/opencv/gstopencvbasetrans.c +++ b/ext/opencv/gstopencvbasetrans.c @@ -213,6 +213,8 @@ gst_opencv_base_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps) { GstOpencvBaseTransform *transform = GST_OPENCV_BASE_TRANSFORM (trans); + GstOpencvBaseTransformClass *klass = + GST_OPENCV_BASE_TRANSFORM_GET_CLASS (transform); gint in_width, in_height; gint in_depth, in_channels; gint out_width, out_height; @@ -236,6 +238,12 @@ gst_opencv_base_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps, return FALSE; } + if (klass->cv_set_caps) { + if (!klass->cv_set_caps(transform, in_width, in_height, in_depth, + in_channels, out_width, out_height, out_depth, out_channels)) + return FALSE; + } + if (transform->cvImage) { cvReleaseImage (&transform->cvImage); } diff --git a/ext/opencv/gstopencvbasetrans.h b/ext/opencv/gstopencvbasetrans.h index db808a8..5ab3ddb 100644 --- a/ext/opencv/gstopencvbasetrans.h +++ b/ext/opencv/gstopencvbasetrans.h @@ -71,6 +71,11 @@ typedef GstFlowReturn (*GstOpencvBaseTransformTransformFunc) (GstOpencvBaseTransform * transform, GstBuffer * buffer, IplImage * img, GstBuffer * outbuf, IplImage * outimg); +typedef gboolean (*GstOpencvBaseTransformSetCaps) + (GstOpencvBaseTransform * transform, gint in_width, gint in_height, + gint in_depth, gint in_channels, gint out_width, gint out_height, + gint out_depth, gint out_channels); + struct _GstOpencvBaseTransform { GstBaseTransform trans; @@ -87,6 +92,8 @@ struct _GstOpencvBaseTransformClass GstOpencvBaseTransformTransformFunc cv_trans_func; GstOpencvBaseTransformTransformIPFunc cv_trans_ip_func; + + GstOpencvBaseTransformSetCaps cv_set_caps; }; GType gst_opencv_base_transform_get_type (void); -- 2.7.4