static void gst_face_blur_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstFaceBlur *filter = GST_FACE_BLUR (object); switch (prop_id) { case PROP_PROFILE: g_value_set_string (value, filter->profile); break; case PROP_SCALE_FACTOR: g_value_set_double (value, filter->scale_factor); break; case PROP_MIN_NEIGHBORS: g_value_set_int (value, filter->min_neighbors); break; case PROP_MIN_SIZE_WIDTH: g_value_set_int (value, filter->min_size_width); break; case PROP_MIN_SIZE_HEIGHT: g_value_set_int (value, filter->min_size_height); break; case PROP_FLAGS: g_value_set_flags (value, filter->flags); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_face_blur_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstFaceBlur *filter = GST_FACE_BLUR (object); switch (prop_id) { case PROP_PROFILE: g_free (filter->profile); filter->profile = g_value_dup_string (value); gst_face_blur_load_profile (filter); filter->sent_profile_load_failed_msg = FALSE; break; case PROP_SCALE_FACTOR: filter->scale_factor = g_value_get_double (value); break; case PROP_MIN_NEIGHBORS: filter->min_neighbors = g_value_get_int (value); break; case PROP_MIN_SIZE_WIDTH: filter->min_size_width = g_value_get_int (value); break; case PROP_MIN_SIZE_HEIGHT: filter->min_size_height = g_value_get_int (value); break; case PROP_FLAGS: filter->flags = g_value_get_flags (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstFlowReturn gst_face_blur_transform_ip (GstOpencvVideoFilter * transform, GstBuffer * buffer, IplImage * img) { GstFaceBlur *filter = GST_FACE_BLUR (transform); CvSeq *faces; int i; if (!filter->cvCascade) return GST_FLOW_OK; cvCvtColor (img, filter->cvGray, CV_RGB2GRAY); cvClearMemStorage (filter->cvStorage); faces = cvHaarDetectObjects (filter->cvGray, filter->cvCascade, filter->cvStorage, 1.1, 2, 0, cvSize (30, 30) #if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) , cvSize (0, 0) #endif ); for (i = 0; i < (faces ? faces->total : 0); i++) { CvRect *r = (CvRect *) cvGetSeqElem (faces, i); cvSetImageROI (img, *r); cvSmooth (img, img, CV_BLUR, 11, 11, 0, 0); cvSmooth (img, img, CV_GAUSSIAN, 11, 11, 0, 0); cvResetImageROI (img); } return GST_FLOW_OK; }
/* this function handles the link with other elements */ static gboolean gst_face_blur_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstFaceBlur *filter; gint width, height; GstStructure *structure; gboolean res = TRUE; filter = GST_FACE_BLUR (parent); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; gst_event_parse_caps (event, &caps); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvStorage = cvCreateMemStorage (0); break; } default: break; } res = gst_pad_event_default (pad, parent, event); return res; }
/* Clean up */ static void gst_face_blur_finalize (GObject * obj) { GstFaceBlur *filter = GST_FACE_BLUR (obj); if (filter->cvImage) { cvReleaseImage (&filter->cvImage); cvReleaseImage (&filter->cvGray); } g_free (filter->profile); G_OBJECT_CLASS (parent_class)->finalize (obj); }
static void gst_face_blur_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstFaceBlur *filter = GST_FACE_BLUR (object); switch (prop_id) { case PROP_PROFILE: g_value_set_string (value, filter->profile); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/* Clean up */ static void gst_face_blur_finalize (GObject * obj) { GstFaceBlur *filter = GST_FACE_BLUR (obj); if (filter->cvGray) cvReleaseImage (&filter->cvGray); if (filter->cvStorage) cvReleaseMemStorage (&filter->cvStorage); if (filter->cvCascade) cvReleaseHaarClassifierCascade (&filter->cvCascade); g_free (filter->profile); G_OBJECT_CLASS (gst_face_blur_parent_class)->finalize (obj); }
static gboolean gst_face_blur_set_caps (GstOpencvVideoFilter * 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) { GstFaceBlur *filter = GST_FACE_BLUR (transform); if (filter->cvGray) cvReleaseImage (&filter->cvGray); filter->cvGray = cvCreateImage (cvSize (in_width, in_height), IPL_DEPTH_8U, 1); if (filter->cvStorage) cvClearMemStorage (filter->cvStorage); else filter->cvStorage = cvCreateMemStorage (0); return TRUE; }
static GstFlowReturn gst_face_blur_transform_ip (GstOpencvVideoFilter * transform, GstBuffer * buffer, IplImage * img) { GstFaceBlur *filter = GST_FACE_BLUR (transform); CvSeq *faces; int i; if (!filter->cvCascade) { if (filter->profile != NULL && filter->sent_profile_load_failed_msg == FALSE) { GST_ELEMENT_WARNING (filter, RESOURCE, NOT_FOUND, ("Profile %s is missing.", filter->profile), ("missing faceblur profile file %s", filter->profile)); filter->sent_profile_load_failed_msg = TRUE; } return GST_FLOW_OK; } cvCvtColor (img, filter->cvGray, CV_RGB2GRAY); cvClearMemStorage (filter->cvStorage); faces = cvHaarDetectObjects (filter->cvGray, filter->cvCascade, filter->cvStorage, filter->scale_factor, filter->min_neighbors, filter->flags, cvSize (filter->min_size_width, filter->min_size_height) #if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) , cvSize (filter->min_size_width + 2, filter->min_size_height + 2) #endif ); for (i = 0; i < (faces ? faces->total : 0); i++) { CvRect *r = (CvRect *) cvGetSeqElem (faces, i); cvSetImageROI (img, *r); cvSmooth (img, img, CV_BLUR, 11, 11, 0, 0); cvSmooth (img, img, CV_GAUSSIAN, 11, 11, 0, 0); cvResetImageROI (img); } return GST_FLOW_OK; }
/* chain function * this function does the actual processing */ static GstFlowReturn gst_face_blur_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) { GstFaceBlur *filter; CvSeq *faces; GstMapInfo info; int i; filter = GST_FACE_BLUR (GST_OBJECT_PARENT (pad)); buf = gst_buffer_make_writable (buf); gst_buffer_map (buf, &info, GST_MAP_READWRITE); filter->cvImage->imageData = (char *) info.data; cvCvtColor (filter->cvImage, filter->cvGray, CV_RGB2GRAY); cvClearMemStorage (filter->cvStorage); if (filter->cvCascade) { faces = cvHaarDetectObjects (filter->cvGray, filter->cvCascade, filter->cvStorage, 1.1, 2, 0, cvSize (30, 30) #if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2) , cvSize (32, 32) #endif ); if (faces && faces->total > 0) { buf = gst_buffer_make_writable (buf); } for (i = 0; i < (faces ? faces->total : 0); i++) { CvRect *r = (CvRect *) cvGetSeqElem (faces, i); cvSetImageROI (filter->cvImage, *r); cvSmooth (filter->cvImage, filter->cvImage, CV_BLUR, 11, 11, 0, 0); cvSmooth (filter->cvImage, filter->cvImage, CV_GAUSSIAN, 11, 11, 0, 0); cvResetImageROI (filter->cvImage); } } /* these filters operate in place, so we push the same buffer */ return gst_pad_push (filter->srcpad, buf); }
/* this function handles the link with other elements */ static gboolean gst_face_blur_set_caps (GstPad * pad, GstCaps * caps) { GstFaceBlur *filter; GstPad *otherpad; gint width, height; GstStructure *structure; filter = GST_FACE_BLUR (gst_pad_get_parent (pad)); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); filter->cvImage = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 3); filter->cvGray = cvCreateImage (cvSize (width, height), IPL_DEPTH_8U, 1); filter->cvStorage = cvCreateMemStorage (0); otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad; gst_object_unref (filter); return gst_pad_set_caps (otherpad, caps); }