Skip to content

Commit

Permalink
Added a Face_Tracking node. This node now includes Optical flow to tr…
Browse files Browse the repository at this point in the history
…ack faces after they have been detected. Both Face_Tracking and Face_Detection now publish the coordinates of the faces. The example node Face_Listener shows how to read the data the other nodes.
  • Loading branch information
phil333 committed Nov 23, 2015
1 parent 571bf61 commit afac1cd
Show file tree
Hide file tree
Showing 11 changed files with 7,445 additions and 21 deletions.
13 changes: 11 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -o0")
# sensor_msgs# std_msgs
# )
generate_dynamic_reconfigure_options(
cfg/face_detection.cfg
cfg/face_det.cfg
cfg/face_track.cfg
)

###################################
Expand Down Expand Up @@ -116,13 +117,15 @@ include_directories(
## Declare a cpp executable
# add_executable(face_detection_node src/face_detection_node.cpp)
add_executable(face_detection src/face_detection.cpp)

add_executable(face_tracking src/face_tracking.cpp)
add_executable(face_listener src/face_listener.cpp)


## Add cmake target dependencies of the executable/library
## as an example, message headers may need to be generated before nodes
# add_dependencies(face_detection_node face_detection_generate_messages_cpp)
add_dependencies(face_detection ${PROJECT_NAME}_gencfg)
add_dependencies(face_tracking ${PROJECT_NAME}_gencfg)



Expand All @@ -133,6 +136,12 @@ add_dependencies(face_detection ${PROJECT_NAME}_gencfg)
target_link_libraries(face_detection
${catkin_LIBRARIES}
)
target_link_libraries(face_tracking
${catkin_LIBRARIES}
)
target_link_libraries(face_listener
${catkin_LIBRARIES}
)


#############
Expand Down
39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@ in a timely manner.


**Why use this package:**
This ROS node is designed to detect faces in images coming from a ROS image
topic. Currently this node displays or publishes an image with the resulting
detections drawn on top of the image. The settings of the detection system
can be easily adapted using ROS rqt_reconfigure.
These ROS nodes are designed to detect and track faces in images coming from a
ROS image topic. The nodes display or publish an image with the resulting
detections drawn on top of the image. The settings of the detection system can
be easily adapted using ROS rqt_reconfigure (rosrun rqt_reconfigure
rqt_reconfigure). The nodes also publish the coordinates of the faces.

**How to Use this package:**
To run the package, use the provided RosLaunch file as follows:
- roslaunch face_detection face_detection.launch
- roslaunch face_detection face_tracking.launch

To see the coordinates published by the nodes, launch the listener node:
- rosrun face_detection face_listener

The settings of the program can be changed with the ROS rqt_reconfigure setup.
- rosrun rqt_reconfigure rqt_reconfigure
Expand All @@ -39,9 +44,31 @@ Once you have the rqt_reconfigure open, change the input image default
different settings are annotated in the dynamic reconfigure setup (hover over
the setting in the rqt_reconfigure for additional information)

**Requirements:**
This node was designed for ROS Indigo and requires a catkin workspace. The node
also makes use of OpenCV. The node has been tested under OpenCV 2.4.8 and 3.0.0.
To be able to get your images into the node, you will need to ROS Vision_OpenCV
package (http://wiki.ros.org/vision_opencv). You will also need a driver which
can read the images from your camera and which can publish these images inside
ROS, like for example ueye_cam (http://wiki.ros.org/ueye_cam) or usb_cam
(http://wiki.ros.org/usb_cam).

**Multi-threading:**
In order to get the best performance out of the detection, you should compile
your OpenCV package with Multi-threading support. OpenCV makes use of TBB
(WITH_TBB=ON)to to enable Multi-threading, for both versions 2.4 and 3.0. Here
is a tutorial on how to install OpenCV with Multi-threading for version 3.0
(http://rodrigoberriel.com/2014/10/installing-opencv-3-0-0-on-ubuntu-14-04/).

WARNING: Reinstalling OpenCV might break some of you other ROS packages, so you
might want to stick to your current version. This node will also run without
Multi-threading support, but especially the Face_Tracking node will run
considerably slower.

**Future plans:**
This package is currently still under development and will shortly support
the publication of the face coordinate.
This package is currently still under development and will be updated
continuously. Please report any problems or desired features, feedback is
always welcome.



Expand Down
89 changes: 89 additions & 0 deletions cfg/face_det.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python
PACKAGE = "face_detection"

from dynamic_reconfigure.parameter_generator_catkin import *


gen = ParameterGenerator()
gen.add("imageInput", str_t, 0,
"Subscribe to this image topic",
"/camera/image_raw")
gen.add("imageOutput", str_t, 0,
"Publish to this image topic",
"/facerec/image_raw")
gen.add("skipFrames", int_t, 0,
"Skip frames that are used for detection",
1, 1, 20)


imgScale_enum = gen.enum([ gen.const("No_Resize", double_t, 1, ""),
gen.const("Resize_by_0_875", double_t, 0.875, ""),
gen.const("Resize_by_0_75", double_t, 0.75, ""),
gen.const("Resize_by_0_625", double_t, 0.625, ""),
gen.const("Resize_by_0_5", double_t, 0.5, ""),
gen.const("Resize_by_0_375", double_t, 0.375, ""),
gen.const("Resize_by_0_25", double_t, 0.25, ""),
gen.const("Resize_by_0_125", double_t, 0.125, "")],
"The detection image will be resized by this value. (great performance increase).")
gen.add("imgScale", double_t, 0, "Select a scaling factor for the detection image", 1, edit_method=imgScale_enum)


gen.add("neighborsValue", int_t, 0,
"The number of neiboring detections required for a sucessfull detection",
2, 0, 8)
gen.add("scaleValue", double_t, 0,
"Multiplicator for each step of the detection",
1.2, 1.01, 1.50)
gen.add("minSize", int_t, 0,
"Minimum size for the search window.",
13, 1, 100)
gen.add("maxSize", int_t, 0,
"Maximum size for the search window.",
250, 5, 1024)

cascade_enum = gen.enum([ gen.const("haarcascade_frontalface_alt", int_t, 0, ""),
gen.const("haarcascade_frontalface_alt2", int_t, 1, ""),
gen.const("haarcascade_frontalface_alt_tree", int_t, 2, ""),
gen.const("haarcascade_frontalface_default", int_t, 3, "")],
"An enum to set size")
gen.add("cascadeValue", int_t, 0, "Select a Cascade", 2, edit_method=cascade_enum)

myflag_enum = gen.enum([ gen.const("Scale", int_t, 0, "Standart type"),
gen.const("Biggest", int_t, 1, "Only returns the biggest detection"),
gen.const("Canny", int_t, 2, "Reduces Canny pruning to reduce the number of false detections"),
gen.const("Rough", int_t, 3, "Rought Detection Search")],
"An enum to set size")
gen.add("myflag", int_t, 0, "Select a type of detection", 2, edit_method=myflag_enum)


debug_enum = gen.enum([ gen.const("No_Debugging", int_t, 0, ""),
gen.const("Displays_Image", int_t, 1, ""),
gen.const("Displays_Detection_Image", int_t, 2, "")],
"An enum to set debugging")
gen.add("debug", int_t, 0, "Select type of debugging", 1, edit_method=debug_enum)

pixelSwitch_enum = gen.enum([ gen.const("Detection_Boxes", int_t, 0, "Draws Detection Boxes"),
gen.const("Pixelise", int_t, 1, "Pixelises the detected Faces")],
"An enum to set pixelSwitch")
gen.add("pixelSwitch", int_t, 1, "Select a detection display type", 0, edit_method=pixelSwitch_enum)



gen.add("contrastFactor", double_t, 0,
"The contrast factor applied to the image to improve detection",
1.5, 0.2, 2.5)
gen.add("histOnOff", int_t, 0,
"Activates histogram equalisation",
0, 0, 1)
gen.add("blurFactor", int_t, 0,
"blurs the image a little, used to reduce noise on full resolution images (imageScaleValue = 1)",
0, 0, 10)
gen.add("brightnessFactor", int_t, 0,
"brightens up the image",
0, 0, 5)
gen.add("inputSkipp", int_t, 0,
"start skipping frames from the input after X frames, generally use '1' for realtime feedback, or much higher values for saving image sequences to disk",
1, 1, 10000)


exit(gen.generate(PACKAGE, "face_detection", "face_det"))
111 changes: 111 additions & 0 deletions cfg/face_track.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python
PACKAGE = "face_detection"

from dynamic_reconfigure.parameter_generator_catkin import *


gen = ParameterGenerator()
gen.add("imageInput", str_t, 0,
"Subscribe to this image topic",
"/ardrone/image_raw")
gen.add("imageOutput", str_t, 0,
"Publish to this image topic",
"/facerec/image_raw")
gen.add("skipFrames", int_t, 0,
"Skip frames that are used for detection",
1, 1, 20)

imgScale_enum = gen.enum([ gen.const("No_Resize", double_t, 1, ""),
gen.const("Resize_by_0_875", double_t, 0.875, ""),
gen.const("Resize_by_0_75", double_t, 0.75, ""),
gen.const("Resize_by_0_625", double_t, 0.625, ""),
gen.const("Resize_by_0_5", double_t, 0.5, ""),
gen.const("Resize_by_0_375", double_t, 0.375, ""),
gen.const("Resize_by_0_25", double_t, 0.25, ""),
gen.const("Resize_by_0_125", double_t, 0.125, "")],
"The detection image will be resized by this value. (great performance increase).")
gen.add("imgScale", double_t, 0, "Select a scaling factor for the detection image", 0.625, edit_method=imgScale_enum)


gen.add("neighborsValue", int_t, 0,
"The number of neiboring detections required for a sucessfull detection",
2, 0, 8)
gen.add("scaleValue", double_t, 0,
"Multiplicator for each step of the detection",
1.2, 1.01, 1.50)
gen.add("minSize", int_t, 0,
"Minimum size for the search window.",
13, 1, 100)
gen.add("maxSize", int_t, 0,
"Maximum size for the search window.",
250, 5, 1024)

cascade_enum = gen.enum([ gen.const("haarcascade_frontalface_alt", int_t, 0, ""),
gen.const("haarcascade_frontalface_alt2", int_t, 1, ""),
gen.const("haarcascade_frontalface_alt_tree", int_t, 2, ""),
gen.const("haarcascade_frontalface_default", int_t, 3, "")],
"An enum to set size")
gen.add("cascadeValue", int_t, 0, "Select a Cascade", 2, edit_method=cascade_enum)

myflag_enum = gen.enum([ gen.const("Scale", int_t, 0, "Standart type"),
gen.const("Biggest", int_t, 1, "Only returns the biggest detection"),
gen.const("Canny", int_t, 2, "Reduces Canny pruning to reduce the number of false detections"),
gen.const("Rough", int_t, 3, "Rought Detection Search")],
"An enum to set size")
gen.add("myflag", int_t, 0, "Select a type of detection", 2, edit_method=myflag_enum)


debug_enum = gen.enum([ gen.const("No_Debugging", int_t, 0, ""),
gen.const("Displays_Image", int_t, 1, ""),
gen.const("Displays_Detection_Image", int_t, 2, ""),
gen.const("Displays_Image_noPublishing", int_t, 3, "")],
"An enum to set debugging")
gen.add("debug", int_t, 0, "Select type of debugging", 1, edit_method=debug_enum)

pixelSwitch_enum = gen.enum([ gen.const("Detection_Boxes", int_t, 0, "Draws Detection Boxes"),
gen.const("Pixelise", int_t, 1, "Pixelises the detected Faces")],
"An enum to set pixelSwitch")
gen.add("pixelSwitch", int_t, 1, "Select a detection display type", 0, edit_method=pixelSwitch_enum)


gen.add("contrastFactor", double_t, 0,
"The contrast factor applied to the image to improve detection",
1.5, 0.2, 2.5)

histOnOff_enum = gen.enum([ gen.const("Histogram_Equalisation_OFF", int_t, 0, ""),
gen.const("Histogram_Equalisation_ON", int_t, 1, "")],
"An enum to set pixelSwitch")
gen.add("histOnOff", int_t, 1, "Select a detection display type", 0, edit_method=histOnOff_enum)



gen.add("blurFactor", int_t, 0,
"blurs the image a little, used to reduce noise on full resolution images (imageScaleValue = 1)",
0, 0, 10)
gen.add("brightnessFactor", int_t, 0,
"brightens up the image",
0, 0, 5)
gen.add("inputSkipp", int_t, 0,
"start skipping frames from the input after X frames, generally use '1' for realtime feedback, or much higher values for saving image sequences to disk",
1, 1, 10000)



gen.add("maxNumFeatures", int_t, 0,
"Number of features used to track each face",
15, 1, 100)

gen.add("maxTrackingNum", int_t, 0,
"Number of times a face is tracked after being detected again",
60, 1, 200)

gen.add("initialDetectionNum", int_t, 0,
"Number of times a face is tracked after the first detection",
4, 1, 10)

gen.add("trackSearchWinSize", int_t, 0,
"Number of times a face is tracked after the first detection",
30, 5, 200)

# needs file name and config name
exit(gen.generate(PACKAGE, "face_tracking", "face_track"))
Loading

0 comments on commit afac1cd

Please sign in to comment.