Skip to content

Commit

Permalink
Merge pull request #105 from mistralol/master
Browse files Browse the repository at this point in the history
Add gstreamer example / test code
  • Loading branch information
ShiqiYu authored Mar 16, 2019
2 parents 89e3a73 + c3b4d04 commit cd6deec
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 0 deletions.
31 changes: 31 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,34 @@ if (DEMO)
add_executable(fdt_demo ${fdt_demo_files})
target_link_libraries(fdt_demo ${fdt_lib_static} ${OpenCV_LIBS})
endif()

if (GSTREAMER)
find_package(OpenCV REQUIRED)

include(FindPkgConfig)
pkg_search_module(GSTREAMER REQUIRED gstreamer-1.0)
pkg_search_module(GSTREAMER_BASE REQUIRED gstreamer-base-1.0)
pkg_search_module(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0)

add_library(gstfacedetect SHARED
example/libfacedetect.cpp
)

include_directories(gstfacedetect PRIVATE
${GSTREAMER_INCLUDE_DIRS}
${GSTREAMER_BASE_INCLUDE_DIRS}
${GSTREAMER_VIDEO_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)

target_link_libraries(gstfacedetect
${GSTREAMER_LIBRARIES}
${GSTREAMER_BASE_LIBRARIES}
${GSTREAMER_VIDEO_LIBRARIES}
${OpenCV_LIBS}
${fdt_lib_shared}
)



endif()
204 changes: 204 additions & 0 deletions example/libfacedetect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>

#include <opencv2/opencv.hpp>
#include "facedetectcnn.h"

/*
Howto run?
GST_DEBUG=3 gst-launch-1.0 filesrc location=input.mp4 ! decodebin \
! videorate ! video/x-raw, framerate=8/1 \
! videoscale ! video/x-raw, width=640, height=480 \
! videoconvert \
! identity sync=true \
! queue max-size-buffers=3 leaky=1 \
! libfacedetect \
! videoconvert \
! xvimagesink sync=false
*/


#define TYPE_FACE_DETECT face_detect_get_type()
G_DECLARE_FINAL_TYPE (FaceDetect, face_detect, FACE, DETECT, GstBaseTransform)

struct _FaceDetect {
GstBaseTransform element;

guint width;
guint height;
guint thresh;
gboolean boxes;
};

G_DEFINE_TYPE (FaceDetect, face_detect, GST_TYPE_BASE_TRANSFORM)

using namespace cv;

#define DEFAULT_THRESHHOLD 75
#define DEFAULT_BOXES TRUE

enum {
PROP_0,
PROP_THRESH,
PROP_BOXES
};

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE("RGB"))
);

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE("RGB"))
);

static void set_property( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec ) {
FaceDetect *self = FACE_DETECT(object);
switch(prop_id) {
case PROP_THRESH:
self->thresh = g_value_get_uint(value);
break;
case PROP_BOXES:
self->boxes = g_value_get_boolean(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}

static void get_property( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec ) {
FaceDetect *self = FACE_DETECT(object);

switch(prop_id) {
case PROP_THRESH:
g_value_set_uint(value, self->thresh);
break;
case PROP_BOXES:
g_value_set_boolean(value, self->boxes);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}

static gboolean set_caps(GstBaseTransform *trans, GstCaps *incaps, GstCaps *outcaps) {
FaceDetect *self = FACE_DETECT(trans);
GstVideoInfo info;

if (gst_video_info_from_caps (&info, incaps) == FALSE) {
return FALSE;
}

GST_INFO("New Width: %d Height: %d", info.width, info.height);
self->width = info.width;
self->height = info.height;

return TRUE;
}

static GstFlowReturn transform_ip(GstBaseTransform *trans, GstBuffer *buf) {
FaceDetect *self = FACE_DETECT(trans);
GST_DEBUG("Processing");

GstMapInfo info;
if (gst_buffer_map(buf, &info, GST_MAP_WRITE) == FALSE) {
GST_ERROR("Cannot map buffer");
return GST_FLOW_ERROR;
}
Size size(self->width, self->height);
Mat image(size, CV_8UC3, (void *) info.data);

unsigned char *pBuffer = (unsigned char *) malloc(0x20000);
int *pResults = facedetect_cnn(pBuffer, (unsigned char*)(image.ptr(0)), image.cols, image.rows, (int)image.step);

for(int i = 0; i < (pResults ? *pResults : 0); i++) {
short * p = ((short*)(pResults+1))+142*i;
int x = p[0];
int y = p[1];
int w = p[2];
int h = p[3];
int neighbors = p[4];
int angle = p[5];

GST_ERROR("face_rect=[%d, %d, %d, %d], neighbors=%d, angle=%d", x,y,w,h,neighbors, angle);
if (neighbors >= self->thresh) {
if (self->boxes) {
rectangle(image, Rect(x, y, w, h), Scalar(0, 255, 0), 2);
}
}
}

free(pBuffer);
gst_buffer_unmap(buf, &info);
return GST_FLOW_OK;
}

static void face_detect_init (FaceDetect *self)
{
self->width = 0;
self->height = 0;
self->thresh = DEFAULT_THRESHHOLD;
self->boxes = DEFAULT_BOXES;
}

static void face_detect_class_init (FaceDetectClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstBaseTransformClass *transform_class = GST_BASE_TRANSFORM_CLASS (klass);

object_class->set_property = set_property;
object_class->get_property = get_property;

transform_class->set_caps = set_caps;
transform_class->transform_ip = transform_ip;

g_object_class_install_property(object_class, PROP_THRESH,
g_param_spec_uint( "thresh", "thresh", "Thresh Hold as a percentage", 0, 100, DEFAULT_THRESHHOLD, G_PARAM_READWRITE)
);

g_object_class_install_property(object_class, PROP_BOXES,
g_param_spec_boolean( "boxes", "boxes", "Draw boxes", DEFAULT_BOXES, G_PARAM_READWRITE)
);

gst_element_class_set_static_metadata(element_class,
"Brightness",
"Sink/Src/Caps",
"Detects faces in images using libfacedetect",
"James Stevenson <[email protected]>"
);

gst_element_class_add_static_pad_template (element_class, &sink_factory);
gst_element_class_add_static_pad_template (element_class, &src_factory);
}


extern "C" gboolean Register_init (GstPlugin *plugin) {
return gst_element_register (plugin, "libfacedetect", GST_RANK_NONE, TYPE_FACE_DETECT);
}

#ifndef PACKAGE
#define PACKAGE "libfacedetect"
#endif

GST_PLUGIN_DEFINE (
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
facedetect,
"Detect faces",
Register_init,
"0.0.0",
"BSD",
"facedetect",
"https://github.com/ShiqiYu/libfacedetection"
)

0 comments on commit cd6deec

Please sign in to comment.