segmentation: Port to GstOpencvVideoFilter base class

This commit is contained in:
Nicolas Dufresne 2016-12-04 14:42:47 -05:00
parent 2b43312a55
commit fc284f7b1c
2 changed files with 31 additions and 39 deletions

View file

@ -81,7 +81,7 @@
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! video/x-raw,width=320,height=240 ! videoconvert ! segmentation test-mode=true method=2 ! videoconvert ! ximagesink
* gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! segmentation test-mode=true method=2 ! videoconvert ! ximagesink
* ]|
* </refsect2>
*/
@ -142,7 +142,8 @@ gst_segmentation_method_get_type (void)
return etype;
}
G_DEFINE_TYPE (GstSegmentation, gst_segmentation, GST_TYPE_VIDEO_FILTER);
G_DEFINE_TYPE (GstSegmentation, gst_segmentation, GST_TYPE_OPENCV_VIDEO_FILTER);
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
@ -159,13 +160,13 @@ static void gst_segmentation_set_property (GObject * object, guint prop_id,
static void gst_segmentation_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_segmentation_transform_ip (GstVideoFilter * btrans,
GstVideoFrame * frame);
static GstFlowReturn gst_segmentation_transform_ip (GstOpencvVideoFilter * filter,
GstBuffer * buffer, IplImage * img);
static gboolean gst_segmentation_stop (GstBaseTransform * basesrc);
static gboolean gst_segmentation_set_info (GstVideoFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info,
GstCaps * outcaps, GstVideoInfo * out_info);
static gboolean gst_segmentation_set_caps (GstOpencvVideoFilter * filter, gint in_width,
gint in_height, gint in_depth, gint in_channels,
gint out_width, gint out_height, gint out_depth, gint out_channels);
static void gst_segmentation_release_all_pointers (GstSegmentation * filter);
/* Codebook algorithm + connected components functions*/
@ -190,7 +191,8 @@ gst_segmentation_class_init (GstSegmentationClass * klass)
GObjectClass *gobject_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseTransformClass *basesrc_class = GST_BASE_TRANSFORM_CLASS (klass);
GstVideoFilterClass *video_class = (GstVideoFilterClass *) klass;
GstOpencvVideoFilterClass *cvfilter_class =
(GstOpencvVideoFilterClass *) klass;
gobject_class = (GObjectClass *) klass;
@ -199,8 +201,8 @@ gst_segmentation_class_init (GstSegmentationClass * klass)
basesrc_class->stop = gst_segmentation_stop;
video_class->transform_frame_ip = gst_segmentation_transform_ip;
video_class->set_info = gst_segmentation_set_info;
cvfilter_class->cv_trans_ip_func = gst_segmentation_transform_ip;
cvfilter_class->cv_set_caps = gst_segmentation_set_caps;
g_object_class_install_property (gobject_class, PROP_METHOD,
g_param_spec_enum ("method",
@ -243,10 +245,9 @@ gst_segmentation_init (GstSegmentation * filter)
filter->test_mode = DEFAULT_TEST_MODE;
filter->framecount = 0;
filter->learning_rate = DEFAULT_LEARNING_RATE;
gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER (filter), TRUE);
}
static void
gst_segmentation_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
@ -291,25 +292,20 @@ gst_segmentation_get_property (GObject * object, guint prop_id,
}
}
/* GstElement vmethod implementations */
/* this function handles the link with other elements */
static gboolean
gst_segmentation_set_info (GstVideoFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info,
GstCaps * outcaps, GstVideoInfo * out_info)
gst_segmentation_set_caps (GstOpencvVideoFilter * filter, gint in_width,
gint in_height, gint in_depth, gint in_channels,
gint out_width, gint out_height, gint out_depth, gint out_channels)
{
GstSegmentation *segmentation = GST_SEGMENTATION (filter);
CvSize size;
size = cvSize (in_info->width, in_info->height);
segmentation->width = in_info->width;
segmentation->height = in_info->height;
/* If cvRGB is already allocated, it means there's a cap modification, */
/* so release first all the images. */
if (NULL != segmentation->cvRGBA)
gst_segmentation_release_all_pointers (segmentation);
size = cvSize (in_width, in_height);
segmentation->width = in_width;
segmentation->height = in_height;
segmentation->cvRGBA = cvCreateImageHeader (size, IPL_DEPTH_8U, 4);
if (NULL != segmentation->cvRGB)
gst_segmentation_release_all_pointers (segmentation);
segmentation->cvRGB = cvCreateImage (size, IPL_DEPTH_8U, 3);
segmentation->cvYUV = cvCreateImage (size, IPL_DEPTH_8U, 3);
@ -343,7 +339,7 @@ gst_segmentation_stop (GstBaseTransform * basesrc)
{
GstSegmentation *filter = GST_SEGMENTATION (basesrc);
if (filter->cvRGBA != NULL)
if (filter->cvRGB != NULL)
gst_segmentation_release_all_pointers (filter);
return TRUE;
@ -352,7 +348,6 @@ gst_segmentation_stop (GstBaseTransform * basesrc)
static void
gst_segmentation_release_all_pointers (GstSegmentation * filter)
{
cvReleaseImage (&filter->cvRGBA);
cvReleaseImage (&filter->cvRGB);
cvReleaseImage (&filter->cvYUV);
cvReleaseImage (&filter->cvFG);
@ -367,18 +362,16 @@ gst_segmentation_release_all_pointers (GstSegmentation * filter)
}
static GstFlowReturn
gst_segmentation_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
gst_segmentation_transform_ip (GstOpencvVideoFilter * cvfilter, GstBuffer * buffer,
IplImage * img)
{
GstSegmentation *filter = GST_SEGMENTATION (btrans);
GstSegmentation *filter = GST_SEGMENTATION (cvfilter);
int j;
/* get image data from the input, which is RGBA */
filter->cvRGBA->imageData = (char *) GST_VIDEO_FRAME_COMP_DATA (frame, 0);
filter->cvRGBA->widthStep = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
filter->framecount++;
/* Image preprocessing: color space conversion etc */
cvCvtColor (filter->cvRGBA, filter->cvRGB, CV_RGBA2RGB);
cvCvtColor (img, filter->cvRGB, CV_RGBA2RGB);
cvCvtColor (filter->cvRGB, filter->cvYUV, CV_RGB2YCrCb);
/* Create and update a fg/bg model using a codebook approach following the
@ -460,10 +453,10 @@ gst_segmentation_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
cvSplit (filter->cvRGB, filter->ch1, filter->ch2, filter->ch3, NULL);
} else
cvSplit (filter->cvRGBA, filter->ch1, filter->ch2, filter->ch3, NULL);
cvSplit (img, filter->ch1, filter->ch2, filter->ch3, NULL);
/* copy anyhow the fg/bg to the alpha channel in the output image */
cvMerge (filter->ch1, filter->ch2, filter->ch3, filter->cvFG, filter->cvRGBA);
cvMerge (filter->ch1, filter->ch2, filter->ch3, filter->cvFG, img);
return GST_FLOW_OK;

View file

@ -45,7 +45,7 @@
#define __GST_SEGMENTATION_H__
#include <gst/gst.h>
#include <gst/video/gstvideofilter.h>
#include <gst/opencv/gstopencvvideofilter.h>
#include <opencv2/core/core_c.h>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/core/version.hpp>
@ -90,13 +90,12 @@ typedef struct code_book
struct _GstSegmentation
{
GstVideoFilter element;
GstOpencvVideoFilter element;
gint method;
gboolean test_mode;
gint width, height;
IplImage *cvRGBA;
IplImage *cvRGB;
IplImage *cvYUV;
@ -125,7 +124,7 @@ struct _GstSegmentation
struct _GstSegmentationClass
{
GstVideoFilterClass parent_class;
GstOpencvVideoFilterClass parent_class;
};
GType gst_segmentation_get_type (void);