mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
grabcut: Port to GstOpencvVideoFilter base class
This commit is contained in:
parent
ee940b130f
commit
2b43312a55
2 changed files with 37 additions and 33 deletions
|
@ -111,7 +111,7 @@ enum
|
||||||
#define DEFAULT_TEST_MODE FALSE
|
#define DEFAULT_TEST_MODE FALSE
|
||||||
#define DEFAULT_SCALE 1.6
|
#define DEFAULT_SCALE 1.6
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstGrabcut, gst_grabcut, GST_TYPE_VIDEO_FILTER);
|
G_DEFINE_TYPE (GstGrabcut, gst_grabcut, GST_TYPE_OPENCV_VIDEO_FILTER);
|
||||||
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
|
@ -128,11 +128,11 @@ static void gst_grabcut_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_grabcut_get_property (GObject * object, guint prop_id,
|
static void gst_grabcut_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static GstFlowReturn gst_grabcut_transform_ip (GstVideoFilter * btrans,
|
static GstFlowReturn gst_grabcut_transform_ip (GstOpencvVideoFilter * filter,
|
||||||
GstVideoFrame * frame);
|
GstBuffer * buf, IplImage * img);
|
||||||
static gboolean gst_grabcut_set_info (GstVideoFilter * filter,
|
static gboolean gst_grabcut_set_caps (GstOpencvVideoFilter * filter,
|
||||||
GstCaps * incaps, GstVideoInfo * in_info,
|
gint in_width, gint in_height, gint in_depth, gint in_channels,
|
||||||
GstCaps * outcaps, GstVideoInfo * out_info);
|
gint out_width, gint out_height, gint out_depth, gint out_channels);
|
||||||
|
|
||||||
static void gst_grabcut_release_all_pointers (GstGrabcut * filter);
|
static void gst_grabcut_release_all_pointers (GstGrabcut * filter);
|
||||||
|
|
||||||
|
@ -153,8 +153,9 @@ gst_grabcut_class_init (GstGrabcutClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
GstOpencvVideoFilterClass *cvbasefilter_class =
|
||||||
|
(GstOpencvVideoFilterClass *) klass;
|
||||||
GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;
|
GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;
|
||||||
GstVideoFilterClass *video_class = (GstVideoFilterClass *) klass;
|
|
||||||
|
|
||||||
gobject_class->set_property = gst_grabcut_set_property;
|
gobject_class->set_property = gst_grabcut_set_property;
|
||||||
gobject_class->get_property = gst_grabcut_get_property;
|
gobject_class->get_property = gst_grabcut_get_property;
|
||||||
|
@ -162,8 +163,8 @@ gst_grabcut_class_init (GstGrabcutClass * klass)
|
||||||
btrans_class->stop = gst_grabcut_stop;
|
btrans_class->stop = gst_grabcut_stop;
|
||||||
btrans_class->passthrough_on_same_caps = TRUE;
|
btrans_class->passthrough_on_same_caps = TRUE;
|
||||||
|
|
||||||
video_class->transform_frame_ip = gst_grabcut_transform_ip;
|
cvbasefilter_class->cv_trans_ip_func = gst_grabcut_transform_ip;
|
||||||
video_class->set_info = gst_grabcut_set_info;
|
cvbasefilter_class->cv_set_caps = gst_grabcut_set_caps;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_TEST_MODE,
|
g_object_class_install_property (gobject_class, PROP_TEST_MODE,
|
||||||
g_param_spec_boolean ("test-mode", "test-mode",
|
g_param_spec_boolean ("test-mode", "test-mode",
|
||||||
|
@ -200,7 +201,8 @@ gst_grabcut_init (GstGrabcut * filter)
|
||||||
{
|
{
|
||||||
filter->test_mode = DEFAULT_TEST_MODE;
|
filter->test_mode = DEFAULT_TEST_MODE;
|
||||||
filter->scale = DEFAULT_SCALE;
|
filter->scale = DEFAULT_SCALE;
|
||||||
gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), FALSE);
|
gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER (filter),
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,20 +247,20 @@ gst_grabcut_get_property (GObject * object, guint prop_id,
|
||||||
/* GstElement vmethod implementations */
|
/* GstElement vmethod implementations */
|
||||||
/* this function handles the link with other elements */
|
/* this function handles the link with other elements */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_grabcut_set_info (GstVideoFilter * filter,
|
gst_grabcut_set_caps (GstOpencvVideoFilter * filter, gint in_width,
|
||||||
GstCaps * incaps, GstVideoInfo * in_info,
|
gint in_height, gint in_depth, gint in_channels, gint out_width,
|
||||||
GstCaps * outcaps, GstVideoInfo * out_info)
|
gint out_height, gint out_depth, gint out_channels)
|
||||||
{
|
{
|
||||||
GstGrabcut *grabcut = GST_GRABCUT (filter);
|
GstGrabcut *grabcut = GST_GRABCUT (filter);
|
||||||
CvSize size;
|
CvSize size;
|
||||||
|
|
||||||
size = cvSize (in_info->width, in_info->height);
|
size = cvSize (in_width, in_height);
|
||||||
/* If cvRGBA is already allocated, it means there's a cap modification,
|
|
||||||
so release first all the images. */
|
/* If cvRGB is already allocated, it means there's a cap modification,
|
||||||
if (NULL != grabcut->cvRGBAin)
|
* so release first all the images. */
|
||||||
|
if (!grabcut->cvRGBin)
|
||||||
gst_grabcut_release_all_pointers (grabcut);
|
gst_grabcut_release_all_pointers (grabcut);
|
||||||
|
|
||||||
grabcut->cvRGBAin = cvCreateImageHeader (size, IPL_DEPTH_8U, 4);
|
|
||||||
grabcut->cvRGBin = cvCreateImage (size, IPL_DEPTH_8U, 3);
|
grabcut->cvRGBin = cvCreateImage (size, IPL_DEPTH_8U, 3);
|
||||||
|
|
||||||
grabcut->cvA = cvCreateImage (size, IPL_DEPTH_8U, 1);
|
grabcut->cvA = cvCreateImage (size, IPL_DEPTH_8U, 1);
|
||||||
|
@ -279,7 +281,7 @@ gst_grabcut_stop (GstBaseTransform * basesrc)
|
||||||
{
|
{
|
||||||
GstGrabcut *filter = GST_GRABCUT (basesrc);
|
GstGrabcut *filter = GST_GRABCUT (basesrc);
|
||||||
|
|
||||||
if (filter->cvRGBAin != NULL)
|
if (filter->cvRGBin != NULL)
|
||||||
gst_grabcut_release_all_pointers (filter);
|
gst_grabcut_release_all_pointers (filter);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -288,7 +290,6 @@ gst_grabcut_stop (GstBaseTransform * basesrc)
|
||||||
static void
|
static void
|
||||||
gst_grabcut_release_all_pointers (GstGrabcut * filter)
|
gst_grabcut_release_all_pointers (GstGrabcut * filter)
|
||||||
{
|
{
|
||||||
cvReleaseImage (&filter->cvRGBAin);
|
|
||||||
cvReleaseImage (&filter->cvRGBin);
|
cvReleaseImage (&filter->cvRGBin);
|
||||||
|
|
||||||
cvReleaseImage (&filter->cvA);
|
cvReleaseImage (&filter->cvA);
|
||||||
|
@ -300,13 +301,14 @@ gst_grabcut_release_all_pointers (GstGrabcut * filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_grabcut_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
|
gst_grabcut_transform_ip (GstOpencvVideoFilter * filter, GstBuffer * buffer,
|
||||||
|
IplImage * img)
|
||||||
{
|
{
|
||||||
GstGrabcut *gc = GST_GRABCUT (btrans);
|
GstGrabcut *gc = GST_GRABCUT (filter);
|
||||||
gint alphapixels;
|
gint alphapixels;
|
||||||
|
|
||||||
GstVideoRegionOfInterestMeta *meta;
|
GstVideoRegionOfInterestMeta *meta;
|
||||||
meta = gst_buffer_get_video_region_of_interest_meta (frame->buffer);
|
meta = gst_buffer_get_video_region_of_interest_meta (buffer);
|
||||||
if (meta) {
|
if (meta) {
|
||||||
gc->facepos.x = (meta->x) - ((gc->scale - 1) * meta->w / 2);
|
gc->facepos.x = (meta->x) - ((gc->scale - 1) * meta->w / 2);
|
||||||
gc->facepos.y = (meta->y) - ((gc->scale - 1) * meta->h / 2);
|
gc->facepos.y = (meta->y) - ((gc->scale - 1) * meta->h / 2);
|
||||||
|
@ -316,11 +318,9 @@ gst_grabcut_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
|
||||||
memset (&(gc->facepos), 0, sizeof (gc->facepos));
|
memset (&(gc->facepos), 0, sizeof (gc->facepos));
|
||||||
}
|
}
|
||||||
|
|
||||||
gc->cvRGBAin->imageData = (char *) GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
|
||||||
|
|
||||||
/* normally input should be RGBA */
|
/* normally input should be RGBA */
|
||||||
cvSplit (gc->cvRGBAin, gc->cvA, gc->cvB, gc->cvC, gc->cvD);
|
cvSplit (img, gc->cvA, gc->cvB, gc->cvC, gc->cvD);
|
||||||
cvCvtColor (gc->cvRGBAin, gc->cvRGBin, CV_BGRA2BGR);
|
cvCvtColor (img, gc->cvRGBin, CV_BGRA2BGR);
|
||||||
compose_matrix_from_image (gc->grabcut_mask, gc->cvD);
|
compose_matrix_from_image (gc->grabcut_mask, gc->cvD);
|
||||||
|
|
||||||
/* Pass cvD to grabcut_mask for the graphcut stuff but that only if
|
/* Pass cvD to grabcut_mask for the graphcut stuff but that only if
|
||||||
|
@ -355,10 +355,10 @@ gst_grabcut_transform_ip (GstVideoFilter * btrans, GstVideoFrame * frame)
|
||||||
cvAnd (gc->grabcut_mask, gc->cvC, gc->cvC, NULL);
|
cvAnd (gc->grabcut_mask, gc->cvC, gc->cvC, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvMerge (gc->cvA, gc->cvB, gc->cvC, gc->cvD, gc->cvRGBAin);
|
cvMerge (gc->cvA, gc->cvB, gc->cvC, gc->cvD, img);
|
||||||
|
|
||||||
if (gc->test_mode) {
|
if (gc->test_mode) {
|
||||||
cvRectangle (gc->cvRGBAin,
|
cvRectangle (img,
|
||||||
cvPoint (gc->facepos.x, gc->facepos.y),
|
cvPoint (gc->facepos.x, gc->facepos.y),
|
||||||
cvPoint (gc->facepos.x + gc->facepos.width,
|
cvPoint (gc->facepos.x + gc->facepos.width,
|
||||||
gc->facepos.y + gc->facepos.height), CV_RGB (255, 0, 255), 1, 8, 0);
|
gc->facepos.y + gc->facepos.height), CV_RGB (255, 0, 255), 1, 8, 0);
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <gst/video/gstvideofilter.h>
|
#include <gst/video/gstvideofilter.h>
|
||||||
|
#include <gst/opencv/gstopencvvideofilter.h>
|
||||||
#include <opencv2/core/core_c.h>
|
#include <opencv2/core/core_c.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,13 +78,16 @@ struct grabcut_params
|
||||||
|
|
||||||
struct _GstGrabcut
|
struct _GstGrabcut
|
||||||
{
|
{
|
||||||
GstVideoFilter element;
|
GstOpencvVideoFilter parent;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gboolean test_mode;
|
gboolean test_mode;
|
||||||
gdouble scale; // grow multiplier to apply to input bbox
|
gdouble scale; // grow multiplier to apply to input bbox
|
||||||
|
|
||||||
IplImage *cvRGBAin, *cvRGBin;
|
IplImage *cvRGBin;
|
||||||
IplImage *cvA, *cvB, *cvC, *cvD;
|
IplImage *cvA;
|
||||||
|
IplImage *cvB;
|
||||||
|
IplImage *cvC;
|
||||||
|
IplImage *cvD;
|
||||||
|
|
||||||
|
|
||||||
CvMat *grabcut_mask; // mask created by graphcut
|
CvMat *grabcut_mask; // mask created by graphcut
|
||||||
|
@ -93,7 +97,7 @@ struct _GstGrabcut
|
||||||
|
|
||||||
struct _GstGrabcutClass
|
struct _GstGrabcutClass
|
||||||
{
|
{
|
||||||
GstVideoFilterClass parent_class;
|
GstOpencvVideoFilterClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_grabcut_get_type (void);
|
GType gst_grabcut_get_type (void);
|
||||||
|
|
Loading…
Reference in a new issue