From 82dc41f1d19f7cc7f59b629f10da7dfd283f762e Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 22 Jan 2024 17:07:42 +0000 Subject: [PATCH 01/14] chore: create lasr_face_recognition package. --- .../lasr_face_recognition/CMakeLists.txt | 208 ++++++++++++++++++ .../lasr_face_recognition/nodes/service | 0 .../vision/lasr_face_recognition/package.xml | 62 ++++++ .../lasr_face_recognition/requirements.in | 1 + common/vision/lasr_face_recognition/setup.py | 11 + .../src/lasr_face_recognition/__init__.py | 0 .../src/lasr_face_recognition/deepface.py | 0 7 files changed, 282 insertions(+) create mode 100644 common/vision/lasr_face_recognition/CMakeLists.txt create mode 100644 common/vision/lasr_face_recognition/nodes/service create mode 100644 common/vision/lasr_face_recognition/package.xml create mode 100644 common/vision/lasr_face_recognition/requirements.in create mode 100644 common/vision/lasr_face_recognition/setup.py create mode 100644 common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py create mode 100644 common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py diff --git a/common/vision/lasr_face_recognition/CMakeLists.txt b/common/vision/lasr_face_recognition/CMakeLists.txt new file mode 100644 index 000000000..426c6cafb --- /dev/null +++ b/common/vision/lasr_face_recognition/CMakeLists.txt @@ -0,0 +1,208 @@ +cmake_minimum_required(VERSION 3.0.2) +project(lasr_face_recognition) + +## Compile as C++11, supported in ROS Kinetic and newer +# add_compile_options(-std=c++11) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + rospy catkin_virtualenv +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +catkin_python_setup() +catkin_generate_virtualenv( + INPUT_REQUIREMENTS requirements.in + PYTHON_INTERPRETER python3.9 +) + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend tag for "message_generation" +## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependency has been pulled in +## but can be declared for certainty nonetheless: +## * add a exec_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# std_msgs # Or other packages containing msgs +# ) + +################################################ +## Declare ROS dynamic reconfigure parameters ## +################################################ + +## To declare and build dynamic reconfigure parameters within this +## package, follow these steps: +## * In the file package.xml: +## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" +## * In this file (CMakeLists.txt): +## * add "dynamic_reconfigure" to +## find_package(catkin REQUIRED COMPONENTS ...) +## * uncomment the "generate_dynamic_reconfigure_options" section below +## and list every .cfg file to be processed + +## Generate dynamic reconfigure parameters in the 'cfg' folder +# generate_dynamic_reconfigure_options( +# cfg/DynReconf1.cfg +# cfg/DynReconf2.cfg +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if your package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( +# INCLUDE_DIRS include +# LIBRARIES lasr_face_recognition +# CATKIN_DEPENDS rospy +# DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +include_directories( +# include + ${catkin_INCLUDE_DIRS} +) + +## Declare a C++ library +# add_library(${PROJECT_NAME} +# src/${PROJECT_NAME}/lasr_face_recognition.cpp +# ) + +## Add cmake target dependencies of the library +## as an example, code may need to be generated before libraries +## either from message generation or dynamic reconfigure +# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Declare a C++ executable +## With catkin_make all packages are built within a single CMake context +## The recommended prefix ensures that target names across packages don't collide +# add_executable(${PROJECT_NAME}_node src/lasr_face_recognition_node.cpp) + +## Rename C++ executable without prefix +## The above recommended prefix causes long target names, the following renames the +## target back to the shorter version for ease of user use +## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" +# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") + +## Add cmake target dependencies of the executable +## same as for the library above +# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) + +## Specify libraries to link a library or executable target against +# target_link_libraries(${PROJECT_NAME}_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +catkin_install_python(PROGRAMS + nodes/service + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +) + +## Mark executables for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html +# install(TARGETS ${PROJECT_NAME}_node +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark libraries for installation +## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html +# install(TARGETS ${PROJECT_NAME} +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_lasr_face_recognition.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/common/vision/lasr_face_recognition/nodes/service b/common/vision/lasr_face_recognition/nodes/service new file mode 100644 index 000000000..e69de29bb diff --git a/common/vision/lasr_face_recognition/package.xml b/common/vision/lasr_face_recognition/package.xml new file mode 100644 index 000000000..b93abae27 --- /dev/null +++ b/common/vision/lasr_face_recognition/package.xml @@ -0,0 +1,62 @@ + + + lasr_face_recognition + 0.0.0 + The lasr_face_recognition package + + + + + jaredswift + + + + + + TODO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + catkin + rospy + rospy + rospy + + + + + + + + diff --git a/common/vision/lasr_face_recognition/requirements.in b/common/vision/lasr_face_recognition/requirements.in new file mode 100644 index 000000000..bfb0272d4 --- /dev/null +++ b/common/vision/lasr_face_recognition/requirements.in @@ -0,0 +1 @@ +deepface==0.0.81 \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/setup.py b/common/vision/lasr_face_recognition/setup.py new file mode 100644 index 000000000..ba3e8b3fa --- /dev/null +++ b/common/vision/lasr_face_recognition/setup.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 + +from distutils.core import setup +from catkin_pkg.python_setup import generate_distutils_setup + +setup_args = generate_distutils_setup( + packages=['lasr_face_recognition'], + package_dir={'': 'src'} +) + +setup(**setup_args) \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py new file mode 100644 index 000000000..e69de29bb From 3bdea087cb6f315dad080785a3f60e67fb9ef937 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 22 Jan 2024 17:48:27 +0000 Subject: [PATCH 02/14] chore: get the package to build. --- .../lasr_face_recognition/CMakeLists.txt | 6 +- .../vision/lasr_face_recognition/package.xml | 11 ++- .../lasr_face_recognition/requirements.in | 2 +- .../lasr_face_recognition/requirements.txt | 68 +++++++++++++++++++ 4 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 common/vision/lasr_face_recognition/requirements.txt diff --git a/common/vision/lasr_face_recognition/CMakeLists.txt b/common/vision/lasr_face_recognition/CMakeLists.txt index 426c6cafb..1980fdbc3 100644 --- a/common/vision/lasr_face_recognition/CMakeLists.txt +++ b/common/vision/lasr_face_recognition/CMakeLists.txt @@ -7,9 +7,7 @@ project(lasr_face_recognition) ## Find catkin macros and libraries ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) ## is used, also find other catkin packages -find_package(catkin REQUIRED COMPONENTS - rospy catkin_virtualenv -) +find_package(catkin REQUIRED catkin_virtualenv) ## System dependencies are found with CMake's conventions # find_package(Boost REQUIRED COMPONENTS system) @@ -119,7 +117,7 @@ catkin_package( ## Your package locations should be listed before other locations include_directories( # include - ${catkin_INCLUDE_DIRS} + #${catkin_INCLUDE_DIRS} ) ## Declare a C++ library diff --git a/common/vision/lasr_face_recognition/package.xml b/common/vision/lasr_face_recognition/package.xml index b93abae27..1a87d55af 100644 --- a/common/vision/lasr_face_recognition/package.xml +++ b/common/vision/lasr_face_recognition/package.xml @@ -7,13 +7,13 @@ - jaredswift + Jared Swift - TODO + MIT @@ -49,14 +49,13 @@ catkin - rospy - rospy - rospy + catkin_virtualenv + lasr_vision_msgs - + requirements.txt diff --git a/common/vision/lasr_face_recognition/requirements.in b/common/vision/lasr_face_recognition/requirements.in index bfb0272d4..8ccc5be4c 100644 --- a/common/vision/lasr_face_recognition/requirements.in +++ b/common/vision/lasr_face_recognition/requirements.in @@ -1 +1 @@ -deepface==0.0.81 \ No newline at end of file +deepface==0.0.81 diff --git a/common/vision/lasr_face_recognition/requirements.txt b/common/vision/lasr_face_recognition/requirements.txt new file mode 100644 index 000000000..8ebce3c87 --- /dev/null +++ b/common/vision/lasr_face_recognition/requirements.txt @@ -0,0 +1,68 @@ +absl-py==2.1.0 # via tensorboard, tensorflow +astunparse==1.6.3 # via tensorflow +beautifulsoup4==4.12.3 # via gdown +blinker==1.7.0 # via flask +cachetools==5.3.2 # via google-auth +certifi==2023.11.17 # via requests +charset-normalizer==3.3.2 # via requests +click==8.1.7 # via flask +deepface==0.0.81 # via -r requirements.in +deprecated==1.2.14 # via deepface +filelock==3.13.1 # via gdown +fire==0.5.0 # via deepface +flask==3.0.1 # via deepface +flatbuffers==23.5.26 # via tensorflow +gast==0.5.4 # via tensorflow +gdown==5.0.0 # via deepface, retina-face +google-auth==2.26.2 # via google-auth-oauthlib, tensorboard +google-auth-oauthlib==1.2.0 # via tensorboard +google-pasta==0.2.0 # via tensorflow +grpcio==1.60.0 # via tensorboard, tensorflow +gunicorn==21.2.0 # via deepface +h5py==3.10.0 # via tensorflow +idna==3.6 # via requests +importlib-metadata==7.0.1 # via flask, markdown +itsdangerous==2.1.2 # via flask +jinja2==3.1.3 # via flask +keras==2.15.0 # via deepface, mtcnn, tensorflow +libclang==16.0.6 # via tensorflow +markdown==3.5.2 # via tensorboard +markupsafe==2.1.4 # via jinja2, werkzeug +ml-dtypes==0.2.0 # via tensorflow +mtcnn==0.1.1 # via deepface +numpy==1.26.3 # via deepface, h5py, ml-dtypes, opencv-python, opt-einsum, pandas, retina-face, tensorboard, tensorflow +oauthlib==3.2.2 # via requests-oauthlib +opencv-python==4.9.0.80 # via deepface, mtcnn, retina-face +opt-einsum==3.3.0 # via tensorflow +packaging==23.2 # via gunicorn, tensorflow +pandas==2.2.0 # via deepface +pillow==10.2.0 # via deepface, retina-face +protobuf==4.23.4 # via tensorboard, tensorflow +pyasn1==0.5.1 # via pyasn1-modules, rsa +pyasn1-modules==0.3.0 # via google-auth +pysocks==1.7.1 # via requests +python-dateutil==2.8.2 # via pandas +pytz==2023.3.post1 # via pandas +requests[socks]==2.31.0 # via gdown, requests-oauthlib, tensorboard +requests-oauthlib==1.3.1 # via google-auth-oauthlib +retina-face==0.0.13 # via deepface +rsa==4.9 # via google-auth +six==1.16.0 # via astunparse, fire, google-pasta, python-dateutil, tensorboard, tensorflow +soupsieve==2.5 # via beautifulsoup4 +tensorboard==2.15.1 # via tensorflow +tensorboard-data-server==0.7.2 # via tensorboard +tensorflow==2.15.0.post1 # via deepface, retina-face +tensorflow-estimator==2.15.0 # via tensorflow +tensorflow-io-gcs-filesystem==0.35.0 # via tensorflow +termcolor==2.4.0 # via fire, tensorflow +tqdm==4.66.1 # via deepface, gdown +typing-extensions==4.9.0 # via tensorflow +tzdata==2023.4 # via pandas +urllib3==2.1.0 # via requests +werkzeug==3.0.1 # via flask, tensorboard +wheel==0.42.0 # via astunparse +wrapt==1.14.1 # via deprecated, tensorflow +zipp==3.17.0 # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# setuptools From 0d02d2a9655fbbb983c81a53d6439a811e29c6d4 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 22 Jan 2024 17:48:46 +0000 Subject: [PATCH 03/14] chore: create service message. --- common/vision/lasr_vision_msgs/CMakeLists.txt | 1 + common/vision/lasr_vision_msgs/srv/Recognise.srv | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 common/vision/lasr_vision_msgs/srv/Recognise.srv diff --git a/common/vision/lasr_vision_msgs/CMakeLists.txt b/common/vision/lasr_vision_msgs/CMakeLists.txt index 491efb56d..0f781a520 100644 --- a/common/vision/lasr_vision_msgs/CMakeLists.txt +++ b/common/vision/lasr_vision_msgs/CMakeLists.txt @@ -59,6 +59,7 @@ add_service_files( YoloDetection.srv BodyPixDetection.srv TorchFaceFeatureDetection.srv + Recognise.srv ) ## Generate actions in the 'action' folder diff --git a/common/vision/lasr_vision_msgs/srv/Recognise.srv b/common/vision/lasr_vision_msgs/srv/Recognise.srv new file mode 100644 index 000000000..ed736ea73 --- /dev/null +++ b/common/vision/lasr_vision_msgs/srv/Recognise.srv @@ -0,0 +1,13 @@ +# Image to run inference on +sensor_msgs/Image image_raw + +# Dataset to use +string dataset + +# How certain the detection should be to include +float32 confidence + +--- + +# Detections +lasr_vision_msgs/Detection[] detections From 8d2ab8ab0cef14d4d755c255e4c179bd8dcdedbf Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 22 Jan 2024 17:48:58 +0000 Subject: [PATCH 04/14] feat: import deepface! --- .../lasr_face_recognition/src/lasr_face_recognition/deepface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py index e69de29bb..d406e3805 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py @@ -0,0 +1,2 @@ +from deepface import DeepFace + From b1ce3e62e38a57fc6680f54b6acefb140dfff2f7 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Tue, 23 Jan 2024 14:34:02 +0000 Subject: [PATCH 05/14] chore: update requirements.txt. --- common/vision/lasr_face_recognition/requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/vision/lasr_face_recognition/requirements.txt b/common/vision/lasr_face_recognition/requirements.txt index 8ebce3c87..382b38ce3 100644 --- a/common/vision/lasr_face_recognition/requirements.txt +++ b/common/vision/lasr_face_recognition/requirements.txt @@ -21,7 +21,6 @@ grpcio==1.60.0 # via tensorboard, tensorflow gunicorn==21.2.0 # via deepface h5py==3.10.0 # via tensorflow idna==3.6 # via requests -importlib-metadata==7.0.1 # via flask, markdown itsdangerous==2.1.2 # via flask jinja2==3.1.3 # via flask keras==2.15.0 # via deepface, mtcnn, tensorflow @@ -62,7 +61,6 @@ urllib3==2.1.0 # via requests werkzeug==3.0.1 # via flask, tensorboard wheel==0.42.0 # via astunparse wrapt==1.14.1 # via deprecated, tensorflow -zipp==3.17.0 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: # setuptools From 5d4741edf56b11d603fe9719064fdd419376976d Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Tue, 23 Jan 2024 14:34:24 +0000 Subject: [PATCH 06/14] chore: bump to 3.10 --- common/vision/lasr_face_recognition/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/vision/lasr_face_recognition/CMakeLists.txt b/common/vision/lasr_face_recognition/CMakeLists.txt index 1980fdbc3..e7bfb8c5e 100644 --- a/common/vision/lasr_face_recognition/CMakeLists.txt +++ b/common/vision/lasr_face_recognition/CMakeLists.txt @@ -19,7 +19,7 @@ find_package(catkin REQUIRED catkin_virtualenv) catkin_python_setup() catkin_generate_virtualenv( INPUT_REQUIREMENTS requirements.in - PYTHON_INTERPRETER python3.9 + PYTHON_INTERPRETER python3.10 ) ################################################ @@ -160,6 +160,7 @@ include_directories( ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination catkin_install_python(PROGRAMS + examples/relay nodes/service DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) From 12f11a9b99f606362a637835e0ad08ac5a0a57b5 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Tue, 23 Jan 2024 14:34:53 +0000 Subject: [PATCH 07/14] feat: working service, example. --- .../lasr_face_recognition/examples/relay | 53 +++++++++++++++++++ .../launch/camera.launch | 23 ++++++++ .../launch/service.launch | 11 ++++ .../lasr_face_recognition/nodes/service | 31 +++++++++++ .../src/lasr_face_recognition/__init__.py | 1 + .../src/lasr_face_recognition/deepface.py | 43 +++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 common/vision/lasr_face_recognition/examples/relay create mode 100644 common/vision/lasr_face_recognition/launch/camera.launch create mode 100644 common/vision/lasr_face_recognition/launch/service.launch diff --git a/common/vision/lasr_face_recognition/examples/relay b/common/vision/lasr_face_recognition/examples/relay new file mode 100644 index 000000000..7e6c8ca08 --- /dev/null +++ b/common/vision/lasr_face_recognition/examples/relay @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +import sys +import rospy +import threading + +from sensor_msgs.msg import Image + +from lasr_vision_msgs.srv import Recognise, RecogniseRequest + +if len(sys.argv) < 3: + print('Usage: rosrun lase_recognition relay ') + exit() + +listen_topic = sys.argv[1] +dataset = sys.argv[2] + +processing = False + +def detect(image): + global processing + processing = True + rospy.loginfo("Received image message") + + try: + detect_service = rospy.ServiceProxy('/recognise', Recognise) + req = RecogniseRequest() + req.image_raw = image + req.dataset = dataset + req.confidence = 0.5 + resp = detect_service(req) + print(resp) + except rospy.ServiceException as e: + rospy.logerr("Service call failed: %s" % e) + finally: + processing = False + +def image_callback(image): + global processing + if processing: + return + + t = threading.Thread(target=detect, args=(image,)) + t.start() + +def listener(): + rospy.init_node('image_listener', anonymous=True) + rospy.wait_for_service('/recognise') + rospy.Subscriber(listen_topic, Image, image_callback) + rospy.spin() + +if __name__ == '__main__': + listener() diff --git a/common/vision/lasr_face_recognition/launch/camera.launch b/common/vision/lasr_face_recognition/launch/camera.launch new file mode 100644 index 000000000..64d5de9d8 --- /dev/null +++ b/common/vision/lasr_face_recognition/launch/camera.launch @@ -0,0 +1,23 @@ + + Perform face recognition using the camera + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/launch/service.launch b/common/vision/lasr_face_recognition/launch/service.launch new file mode 100644 index 000000000..60fcc1072 --- /dev/null +++ b/common/vision/lasr_face_recognition/launch/service.launch @@ -0,0 +1,11 @@ + + Start the Face Recognition service + + debug:=true + + + + + + + \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/nodes/service b/common/vision/lasr_face_recognition/nodes/service index e69de29bb..4c566fd1d 100644 --- a/common/vision/lasr_face_recognition/nodes/service +++ b/common/vision/lasr_face_recognition/nodes/service @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +import re +import rospy +import lasr_face_recognition as face_recognition +from sensor_msgs.msg import Image +from lasr_vision_msgs.srv import Recognise, RecogniseRequest, RecogniseResponse + +rospy.init_node('recognise_service') + +# Determine variables +DEBUG = rospy.get_param('~debug', False) + +debug_publishers = {} +if DEBUG: + debug_publisher = rospy.Publisher("/recognise/debug", Image, queue_size=1) + +def detect(request : RecogniseRequest) -> RecogniseResponse: + debug_publisher = None + if DEBUG: + if request.dataset in debug_publishers: + debug_publisher = debug_publishers[request.dataset] + else: + topic_name = re.sub(r'[\W_]+', '', request.dataset) + debug_publisher = rospy.Publisher(f'/recognise/debug/{topic_name}', Image, queue_size=1) + return face_recognition.detect(request, debug_publisher) + + +rospy.Service('/recognise', Recognise, detect) +rospy.loginfo('Face Recognition service starter') +rospy.spin() \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py index e69de29bb..4b0a31582 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py @@ -0,0 +1 @@ +from .deepface import detect diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py index d406e3805..dcbb97755 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py @@ -1,2 +1,45 @@ from deepface import DeepFace +import cv2 +import cv2_img +import rospkg +import rospy +import os +from collections import defaultdict +from lasr_vision_msgs.msg import Detection +from lasr_vision_msgs.srv import RecogniseRequest, RecogniseResponse + +DATASET_ROOT = os.path.join(rospkg.RosPack().get_path("lasr_face_recognition"), "datasets") + +def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) -> RecogniseResponse: + + # Decode the image + rospy.loginfo("Decoding") + cv_im = cv2_img.msg_to_cv2_img(request.image_raw) + + + + # Run inference + rospy.loginfo("Running inference") + result = DeepFace.find(cv_im, os.path.join(DATASET_ROOT, request.dataset), enforce_detection=False) + + response = RecogniseResponse() + + for row in result: + if row.empty: + continue + detection = Detection() + detection.name = row["identity"][0].split("/")[-1].split("_")[0] + x, y, w, h = row["source_x"][0], row["source_y"][0], row["source_w"][0], row["source_h"][0] + detection.xywh = [x, y, w, h] + response.detections.append(detection) + + # Draw bounding boxes and labels for debugging + cv2.rectangle(cv_im, (x, y), (x+w, y+h), (0, 0, 255), 2) + cv2.putText(cv_im, detection.name, (x,y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) + + # publish to debug topic + if debug_publisher is not None: + debug_publisher.publish(cv2_img.cv2_img_to_msg(cv_im)) + + return response \ No newline at end of file From 4412e848212f5d98bbd6cde4af5d2b9bd419df9a Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Tue, 23 Jan 2024 14:35:31 +0000 Subject: [PATCH 08/14] chore: add .gitkeep. --- common/vision/lasr_face_recognition/datasets/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 common/vision/lasr_face_recognition/datasets/.gitkeep diff --git a/common/vision/lasr_face_recognition/datasets/.gitkeep b/common/vision/lasr_face_recognition/datasets/.gitkeep new file mode 100644 index 000000000..e69de29bb From 5acf0fcde66f8a265bdad7c771af9fb47d176ca8 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Wed, 24 Jan 2024 11:54:06 +0000 Subject: [PATCH 09/14] feat: add create_dataset script. --- .../lasr_face_recognition/CMakeLists.txt | 1 + .../scripts/create_dataset | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 common/vision/lasr_face_recognition/scripts/create_dataset diff --git a/common/vision/lasr_face_recognition/CMakeLists.txt b/common/vision/lasr_face_recognition/CMakeLists.txt index e7bfb8c5e..58560d36a 100644 --- a/common/vision/lasr_face_recognition/CMakeLists.txt +++ b/common/vision/lasr_face_recognition/CMakeLists.txt @@ -161,6 +161,7 @@ include_directories( ## in contrast to setup.py, you can choose the destination catkin_install_python(PROGRAMS examples/relay + examples/greet nodes/service DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) diff --git a/common/vision/lasr_face_recognition/scripts/create_dataset b/common/vision/lasr_face_recognition/scripts/create_dataset new file mode 100644 index 000000000..e690cbcc4 --- /dev/null +++ b/common/vision/lasr_face_recognition/scripts/create_dataset @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import sys + +if len(sys.argv) < 3: + print("usage: rosrun lasr_face_recognition create_dataset.py [size=20]") + exit(0) + +dataset = sys.argv[1] +name = sys.argv[2] + +if len(sys.argv) > 3: + size = sys.argv[3] +else: + size = 20 + +import rospy +import rospkg +from sensor_msgs.msg import Image +import os +import cv2_img +import cv2 + +DATASET_ROOT = os.path.join(rospkg.RosPack().get_path("lasr_face_recognition"), "datasets") +DATASET_PATH = os.path.join(DATASET_ROOT, dataset, name) +if not os.path.exists(DATASET_PATH): + os.makedirs(DATASET_PATH) + +rospy.init_node("create_dataset") +rospy.loginfo(f"Taking {size} pictures of {name} and saving to {DATASET_PATH}") + +for i in range(size): + img_msg = rospy.wait_for_message("/xtion/rgb/image_raw", Image) + cv_im = cv2_img.msg_to_cv2_img(img_msg) + cv2.imwrite(os.path.join(DATASET_PATH), f"{name}_{i+1}.png", cv_im) + rospy.loginfo(f"Took picutre {i+1}") + rospy.sleep(rospy.Duration(1.0)) From faace13e986a18bc555950333af1c184ed8560d8 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Wed, 24 Jan 2024 11:54:22 +0000 Subject: [PATCH 10/14] refactor: drop defaultdict import. --- .../src/lasr_face_recognition/deepface.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py index dcbb97755..73102113f 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py @@ -4,7 +4,6 @@ import rospkg import rospy import os -from collections import defaultdict from lasr_vision_msgs.msg import Detection from lasr_vision_msgs.srv import RecogniseRequest, RecogniseResponse @@ -17,8 +16,6 @@ def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) rospy.loginfo("Decoding") cv_im = cv2_img.msg_to_cv2_img(request.image_raw) - - # Run inference rospy.loginfo("Running inference") result = DeepFace.find(cv_im, os.path.join(DATASET_ROOT, request.dataset), enforce_detection=False) From 684151d756d3febe9bb18a35903fb083c27173a6 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Wed, 24 Jan 2024 13:49:22 +0000 Subject: [PATCH 11/14] feat(WIP): create a dataset. --- .../lasr_face_recognition/CMakeLists.txt | 1 + .../lasr_face_recognition/examples/greet | 57 +++++++++++++++++++ .../launch/camera.launch | 2 +- .../lasr_face_recognition/requirements.in | 1 + .../scripts/create_dataset | 13 +++-- .../src/lasr_face_recognition/__init__.py | 2 +- .../src/lasr_face_recognition/deepface.py | 16 +++++- 7 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 common/vision/lasr_face_recognition/examples/greet diff --git a/common/vision/lasr_face_recognition/CMakeLists.txt b/common/vision/lasr_face_recognition/CMakeLists.txt index 58560d36a..65e6b0e83 100644 --- a/common/vision/lasr_face_recognition/CMakeLists.txt +++ b/common/vision/lasr_face_recognition/CMakeLists.txt @@ -160,6 +160,7 @@ include_directories( ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination catkin_install_python(PROGRAMS + scripts/create_dataset examples/relay examples/greet nodes/service diff --git a/common/vision/lasr_face_recognition/examples/greet b/common/vision/lasr_face_recognition/examples/greet new file mode 100644 index 000000000..63778c6af --- /dev/null +++ b/common/vision/lasr_face_recognition/examples/greet @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import sys +import rospy +from copy import deepcopy + +from sensor_msgs.msg import Image + +from lasr_vision_msgs.srv import Recognise, RecogniseRequest + +if len(sys.argv) < 3: + print('Usage: rosrun lase_recognition greet ') + exit() + +listen_topic = sys.argv[1] +dataset = sys.argv[2] +people_in_frame = [] +last_received_time = None + + +def detect(image): + rospy.loginfo("Received image message") + global people_in_frame + people_in_frame = [] + try: + detect_service = rospy.ServiceProxy('/recognise', Recognise) + req = RecogniseRequest() + req.image_raw = image + req.dataset = dataset + req.confidence = 0.5 + resp = detect_service(req) + for detection in resp.detections: + people_in_frame.append(detection.name) + print(resp) + except rospy.ServiceException as e: + rospy.logerr("Service call failed: %s" % e) + +def greet(): + print(f"Hello, {' '.join(people_in_frame)}") + +def image_callback(image): + global last_received_time + if last_received_time is None or rospy.Time.now() - last_received_time >= rospy.Duration(5.0): + prev_people_in_frame = deepcopy(people_in_frame) + detect(image) + if people_in_frame != prev_people_in_frame: + greet() + last_received_time = rospy.Time.now() + +def listener(): + rospy.init_node('image_listener', anonymous=True) + rospy.wait_for_service('/recognise') + rospy.Subscriber(listen_topic, Image, image_callback) + rospy.spin() + +if __name__ == '__main__': + listener() diff --git a/common/vision/lasr_face_recognition/launch/camera.launch b/common/vision/lasr_face_recognition/launch/camera.launch index 64d5de9d8..0f548e569 100644 --- a/common/vision/lasr_face_recognition/launch/camera.launch +++ b/common/vision/lasr_face_recognition/launch/camera.launch @@ -11,7 +11,7 @@ - + diff --git a/common/vision/lasr_face_recognition/requirements.in b/common/vision/lasr_face_recognition/requirements.in index 8ccc5be4c..fa409e386 100644 --- a/common/vision/lasr_face_recognition/requirements.in +++ b/common/vision/lasr_face_recognition/requirements.in @@ -1 +1,2 @@ deepface==0.0.81 +numpy>=1.2.1 \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/scripts/create_dataset b/common/vision/lasr_face_recognition/scripts/create_dataset index e690cbcc4..0ab15c523 100644 --- a/common/vision/lasr_face_recognition/scripts/create_dataset +++ b/common/vision/lasr_face_recognition/scripts/create_dataset @@ -1,9 +1,10 @@ #!/usr/bin/env python3 import sys +import lasr_face_recognition as face_recognition if len(sys.argv) < 3: - print("usage: rosrun lasr_face_recognition create_dataset.py [size=20]") + print("usage: rosrun lasr_face_recognition create_dataset.py [size=50]") exit(0) dataset = sys.argv[1] @@ -12,7 +13,7 @@ name = sys.argv[2] if len(sys.argv) > 3: size = sys.argv[3] else: - size = 20 + size = 50 import rospy import rospkg @@ -32,6 +33,8 @@ rospy.loginfo(f"Taking {size} pictures of {name} and saving to {DATASET_PATH}") for i in range(size): img_msg = rospy.wait_for_message("/xtion/rgb/image_raw", Image) cv_im = cv2_img.msg_to_cv2_img(img_msg) - cv2.imwrite(os.path.join(DATASET_PATH), f"{name}_{i+1}.png", cv_im) - rospy.loginfo(f"Took picutre {i+1}") - rospy.sleep(rospy.Duration(1.0)) + face_cropped_cv_im = face_recognition.detect_face(cv_im) + if face_cropped_cv_im is None: + continue + cv2.imwrite(os.path.join(DATASET_PATH, f"{name}_{i+1}.png"), face_cropped_cv_im) + rospy.loginfo(f"Took picture {i+1}") diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py index 4b0a31582..a2a6b55de 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py @@ -1 +1 @@ -from .deepface import detect +from .deepface import detect, detect_face \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py index 73102113f..c50f066c6 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py @@ -4,12 +4,23 @@ import rospkg import rospy import os +import numpy as np from lasr_vision_msgs.msg import Detection from lasr_vision_msgs.srv import RecogniseRequest, RecogniseResponse DATASET_ROOT = os.path.join(rospkg.RosPack().get_path("lasr_face_recognition"), "datasets") +Mat = int#np.typing.NDArray[np.uint8] + +def detect_face(cv_im : Mat) -> Mat | None: + faces = DeepFace.extract_faces(cv_im, target_size=(224, 244), detector_backend="mtcnn", enforce_detection = False) + if not faces: + return None + facial_area = faces[0]["facial_area"] + x,y,w,h = facial_area["x"], facial_area["y"], facial_area["w"], facial_area["h"] + return cv_im[:][y:y+h, x:x+w] + def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) -> RecogniseResponse: # Decode the image @@ -18,7 +29,7 @@ def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) # Run inference rospy.loginfo("Running inference") - result = DeepFace.find(cv_im, os.path.join(DATASET_ROOT, request.dataset), enforce_detection=False) + result = DeepFace.find(cv_im, os.path.join(DATASET_ROOT, request.dataset), enforce_detection=False, silent=True) response = RecogniseResponse() @@ -29,11 +40,12 @@ def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) detection.name = row["identity"][0].split("/")[-1].split("_")[0] x, y, w, h = row["source_x"][0], row["source_y"][0], row["source_w"][0], row["source_h"][0] detection.xywh = [x, y, w, h] + confidence = row["VGG-Face_cosine"] response.detections.append(detection) # Draw bounding boxes and labels for debugging cv2.rectangle(cv_im, (x, y), (x+w, y+h), (0, 0, 255), 2) - cv2.putText(cv_im, detection.name, (x,y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) + cv2.putText(cv_im, f"{detection.name} ({confidence})", (x,y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # publish to debug topic if debug_publisher is not None: From 9791b2b328638a3c5624ed2eb3314d0fbf1de170 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 29 Jan 2024 11:56:13 +0000 Subject: [PATCH 12/14] refactor: formatting. --- .../src/lasr_face_recognition/__init__.py | 2 +- .../src/lasr_face_recognition/deepface.py | 51 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py index a2a6b55de..5a5bb56d8 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py @@ -1 +1 @@ -from .deepface import detect, detect_face \ No newline at end of file +from .deepface import detect, detect_face diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py index c50f066c6..6fa062383 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py +++ b/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py @@ -9,27 +9,39 @@ from lasr_vision_msgs.msg import Detection from lasr_vision_msgs.srv import RecogniseRequest, RecogniseResponse -DATASET_ROOT = os.path.join(rospkg.RosPack().get_path("lasr_face_recognition"), "datasets") +DATASET_ROOT = os.path.join( + rospkg.RosPack().get_path("lasr_face_recognition"), "datasets" +) -Mat = int#np.typing.NDArray[np.uint8] +Mat = int # np.typing.NDArray[np.uint8] -def detect_face(cv_im : Mat) -> Mat | None: - faces = DeepFace.extract_faces(cv_im, target_size=(224, 244), detector_backend="mtcnn", enforce_detection = False) + +def detect_face(cv_im: Mat) -> Mat | None: + faces = DeepFace.extract_faces( + cv_im, target_size=(224, 244), detector_backend="mtcnn", enforce_detection=False + ) if not faces: return None facial_area = faces[0]["facial_area"] - x,y,w,h = facial_area["x"], facial_area["y"], facial_area["w"], facial_area["h"] - return cv_im[:][y:y+h, x:x+w] + x, y, w, h = facial_area["x"], facial_area["y"], facial_area["w"], facial_area["h"] + return cv_im[:][y : y + h, x : x + w] + -def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) -> RecogniseResponse: - +def detect( + request: RecogniseRequest, debug_publisher: rospy.Publisher | None +) -> RecogniseResponse: # Decode the image rospy.loginfo("Decoding") cv_im = cv2_img.msg_to_cv2_img(request.image_raw) # Run inference rospy.loginfo("Running inference") - result = DeepFace.find(cv_im, os.path.join(DATASET_ROOT, request.dataset), enforce_detection=False, silent=True) + result = DeepFace.find( + cv_im, + os.path.join(DATASET_ROOT, request.dataset), + enforce_detection=False, + silent=True, + ) response = RecogniseResponse() @@ -38,17 +50,30 @@ def detect(request : RecogniseRequest, debug_publisher: rospy.Publisher | None) continue detection = Detection() detection.name = row["identity"][0].split("/")[-1].split("_")[0] - x, y, w, h = row["source_x"][0], row["source_y"][0], row["source_w"][0], row["source_h"][0] + x, y, w, h = ( + row["source_x"][0], + row["source_y"][0], + row["source_w"][0], + row["source_h"][0], + ) detection.xywh = [x, y, w, h] confidence = row["VGG-Face_cosine"] response.detections.append(detection) # Draw bounding boxes and labels for debugging - cv2.rectangle(cv_im, (x, y), (x+w, y+h), (0, 0, 255), 2) - cv2.putText(cv_im, f"{detection.name} ({confidence})", (x,y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) + cv2.rectangle(cv_im, (x, y), (x + w, y + h), (0, 0, 255), 2) + cv2.putText( + cv_im, + f"{detection.name} ({confidence})", + (x, y - 5), + cv2.FONT_HERSHEY_SIMPLEX, + 0.5, + (0, 255, 0), + 2, + ) # publish to debug topic if debug_publisher is not None: debug_publisher.publish(cv2_img.cv2_img_to_msg(cv_im)) - return response \ No newline at end of file + return response From d51889e35c6351e1897237a33ff4f2ac1825e449 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 29 Jan 2024 11:56:26 +0000 Subject: [PATCH 13/14] chore: add .gitignore. --- common/vision/lasr_face_recognition/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 common/vision/lasr_face_recognition/.gitignore diff --git a/common/vision/lasr_face_recognition/.gitignore b/common/vision/lasr_face_recognition/.gitignore new file mode 100644 index 000000000..5c47c3ae0 --- /dev/null +++ b/common/vision/lasr_face_recognition/.gitignore @@ -0,0 +1,3 @@ +# keep datasets folder +datasets/** +!datasets/.gitkeep From a8cd19cc3bd17bbd83e19af6a280e1b27ee3ab68 Mon Sep 17 00:00:00 2001 From: Jared Swift Date: Mon, 29 Jan 2024 11:58:14 +0000 Subject: [PATCH 14/14] chore: rename package to adhere naming conventions. --- .../.gitignore | 0 .../CMakeLists.txt | 10 ++++----- .../datasets/.gitkeep | 0 .../examples/greet | 0 .../examples/relay | 0 .../launch/camera.launch | 4 ++-- .../launch/service.launch | 2 +- .../nodes/service | 21 +++++++++++-------- .../package.xml | 6 +++--- .../requirements.in | 0 .../requirements.txt | 0 .../scripts/create_dataset | 10 ++++++--- .../setup.py | 5 ++--- .../src/lasr_vision_deepface}/__init__.py | 0 .../src/lasr_vision_deepface}/deepface.py | 2 +- 15 files changed, 33 insertions(+), 27 deletions(-) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/.gitignore (100%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/CMakeLists.txt (96%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/datasets/.gitkeep (100%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/examples/greet (100%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/examples/relay (100%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/launch/camera.launch (76%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/launch/service.launch (78%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/nodes/service (51%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/package.xml (93%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/requirements.in (100%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/requirements.txt (100%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/scripts/create_dataset (77%) rename common/vision/{lasr_face_recognition => lasr_vision_deepface}/setup.py (65%) rename common/vision/{lasr_face_recognition/src/lasr_face_recognition => lasr_vision_deepface/src/lasr_vision_deepface}/__init__.py (100%) rename common/vision/{lasr_face_recognition/src/lasr_face_recognition => lasr_vision_deepface/src/lasr_vision_deepface}/deepface.py (96%) diff --git a/common/vision/lasr_face_recognition/.gitignore b/common/vision/lasr_vision_deepface/.gitignore similarity index 100% rename from common/vision/lasr_face_recognition/.gitignore rename to common/vision/lasr_vision_deepface/.gitignore diff --git a/common/vision/lasr_face_recognition/CMakeLists.txt b/common/vision/lasr_vision_deepface/CMakeLists.txt similarity index 96% rename from common/vision/lasr_face_recognition/CMakeLists.txt rename to common/vision/lasr_vision_deepface/CMakeLists.txt index 65e6b0e83..b22bda630 100644 --- a/common/vision/lasr_face_recognition/CMakeLists.txt +++ b/common/vision/lasr_vision_deepface/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.0.2) -project(lasr_face_recognition) +project(lasr_vision_deepface) ## Compile as C++11, supported in ROS Kinetic and newer # add_compile_options(-std=c++11) @@ -104,7 +104,7 @@ catkin_generate_virtualenv( ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( # INCLUDE_DIRS include -# LIBRARIES lasr_face_recognition +# LIBRARIES lasr_vision_deepface # CATKIN_DEPENDS rospy # DEPENDS system_lib ) @@ -122,7 +122,7 @@ include_directories( ## Declare a C++ library # add_library(${PROJECT_NAME} -# src/${PROJECT_NAME}/lasr_face_recognition.cpp +# src/${PROJECT_NAME}/lasr_vision_deepface.cpp # ) ## Add cmake target dependencies of the library @@ -133,7 +133,7 @@ include_directories( ## Declare a C++ executable ## With catkin_make all packages are built within a single CMake context ## The recommended prefix ensures that target names across packages don't collide -# add_executable(${PROJECT_NAME}_node src/lasr_face_recognition_node.cpp) +# add_executable(${PROJECT_NAME}_node src/lasr_vision_deepface_node.cpp) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the @@ -200,7 +200,7 @@ catkin_install_python(PROGRAMS ############# ## Add gtest based cpp test target and link libraries -# catkin_add_gtest(${PROJECT_NAME}-test test/test_lasr_face_recognition.cpp) +# catkin_add_gtest(${PROJECT_NAME}-test test/test_lasr_vision_deepface.cpp) # if(TARGET ${PROJECT_NAME}-test) # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) # endif() diff --git a/common/vision/lasr_face_recognition/datasets/.gitkeep b/common/vision/lasr_vision_deepface/datasets/.gitkeep similarity index 100% rename from common/vision/lasr_face_recognition/datasets/.gitkeep rename to common/vision/lasr_vision_deepface/datasets/.gitkeep diff --git a/common/vision/lasr_face_recognition/examples/greet b/common/vision/lasr_vision_deepface/examples/greet similarity index 100% rename from common/vision/lasr_face_recognition/examples/greet rename to common/vision/lasr_vision_deepface/examples/greet diff --git a/common/vision/lasr_face_recognition/examples/relay b/common/vision/lasr_vision_deepface/examples/relay similarity index 100% rename from common/vision/lasr_face_recognition/examples/relay rename to common/vision/lasr_vision_deepface/examples/relay diff --git a/common/vision/lasr_face_recognition/launch/camera.launch b/common/vision/lasr_vision_deepface/launch/camera.launch similarity index 76% rename from common/vision/lasr_face_recognition/launch/camera.launch rename to common/vision/lasr_vision_deepface/launch/camera.launch index 0f548e569..a9c85fbb1 100644 --- a/common/vision/lasr_face_recognition/launch/camera.launch +++ b/common/vision/lasr_vision_deepface/launch/camera.launch @@ -6,7 +6,7 @@ - + @@ -14,7 +14,7 @@ - + diff --git a/common/vision/lasr_face_recognition/launch/service.launch b/common/vision/lasr_vision_deepface/launch/service.launch similarity index 78% rename from common/vision/lasr_face_recognition/launch/service.launch rename to common/vision/lasr_vision_deepface/launch/service.launch index 60fcc1072..337c5ae88 100644 --- a/common/vision/lasr_face_recognition/launch/service.launch +++ b/common/vision/lasr_vision_deepface/launch/service.launch @@ -5,7 +5,7 @@ - + \ No newline at end of file diff --git a/common/vision/lasr_face_recognition/nodes/service b/common/vision/lasr_vision_deepface/nodes/service similarity index 51% rename from common/vision/lasr_face_recognition/nodes/service rename to common/vision/lasr_vision_deepface/nodes/service index 4c566fd1d..12149844c 100644 --- a/common/vision/lasr_face_recognition/nodes/service +++ b/common/vision/lasr_vision_deepface/nodes/service @@ -2,30 +2,33 @@ import re import rospy -import lasr_face_recognition as face_recognition +import lasr_vision_deepface as face_recognition from sensor_msgs.msg import Image from lasr_vision_msgs.srv import Recognise, RecogniseRequest, RecogniseResponse -rospy.init_node('recognise_service') +rospy.init_node("recognise_service") # Determine variables -DEBUG = rospy.get_param('~debug', False) +DEBUG = rospy.get_param("~debug", False) debug_publishers = {} if DEBUG: debug_publisher = rospy.Publisher("/recognise/debug", Image, queue_size=1) -def detect(request : RecogniseRequest) -> RecogniseResponse: + +def detect(request: RecogniseRequest) -> RecogniseResponse: debug_publisher = None if DEBUG: if request.dataset in debug_publishers: debug_publisher = debug_publishers[request.dataset] else: - topic_name = re.sub(r'[\W_]+', '', request.dataset) - debug_publisher = rospy.Publisher(f'/recognise/debug/{topic_name}', Image, queue_size=1) + topic_name = re.sub(r"[\W_]+", "", request.dataset) + debug_publisher = rospy.Publisher( + f"/recognise/debug/{topic_name}", Image, queue_size=1 + ) return face_recognition.detect(request, debug_publisher) -rospy.Service('/recognise', Recognise, detect) -rospy.loginfo('Face Recognition service starter') -rospy.spin() \ No newline at end of file +rospy.Service("/recognise", Recognise, detect) +rospy.loginfo("Face Recognition service starter") +rospy.spin() diff --git a/common/vision/lasr_face_recognition/package.xml b/common/vision/lasr_vision_deepface/package.xml similarity index 93% rename from common/vision/lasr_face_recognition/package.xml rename to common/vision/lasr_vision_deepface/package.xml index 1a87d55af..798e7e650 100644 --- a/common/vision/lasr_face_recognition/package.xml +++ b/common/vision/lasr_vision_deepface/package.xml @@ -1,8 +1,8 @@ - lasr_face_recognition + lasr_vision_deepface 0.0.0 - The lasr_face_recognition package + The lasr_vision_deepface package @@ -19,7 +19,7 @@ - + diff --git a/common/vision/lasr_face_recognition/requirements.in b/common/vision/lasr_vision_deepface/requirements.in similarity index 100% rename from common/vision/lasr_face_recognition/requirements.in rename to common/vision/lasr_vision_deepface/requirements.in diff --git a/common/vision/lasr_face_recognition/requirements.txt b/common/vision/lasr_vision_deepface/requirements.txt similarity index 100% rename from common/vision/lasr_face_recognition/requirements.txt rename to common/vision/lasr_vision_deepface/requirements.txt diff --git a/common/vision/lasr_face_recognition/scripts/create_dataset b/common/vision/lasr_vision_deepface/scripts/create_dataset similarity index 77% rename from common/vision/lasr_face_recognition/scripts/create_dataset rename to common/vision/lasr_vision_deepface/scripts/create_dataset index 0ab15c523..a3b502c0b 100644 --- a/common/vision/lasr_face_recognition/scripts/create_dataset +++ b/common/vision/lasr_vision_deepface/scripts/create_dataset @@ -1,10 +1,12 @@ #!/usr/bin/env python3 import sys -import lasr_face_recognition as face_recognition +import lasr_vision_deepface as face_recognition if len(sys.argv) < 3: - print("usage: rosrun lasr_face_recognition create_dataset.py [size=50]") + print( + "usage: rosrun lasr_vision_deepface create_dataset.py [size=50]" + ) exit(0) dataset = sys.argv[1] @@ -22,7 +24,9 @@ import os import cv2_img import cv2 -DATASET_ROOT = os.path.join(rospkg.RosPack().get_path("lasr_face_recognition"), "datasets") +DATASET_ROOT = os.path.join( + rospkg.RosPack().get_path("lasr_vision_deepface"), "datasets" +) DATASET_PATH = os.path.join(DATASET_ROOT, dataset, name) if not os.path.exists(DATASET_PATH): os.makedirs(DATASET_PATH) diff --git a/common/vision/lasr_face_recognition/setup.py b/common/vision/lasr_vision_deepface/setup.py similarity index 65% rename from common/vision/lasr_face_recognition/setup.py rename to common/vision/lasr_vision_deepface/setup.py index ba3e8b3fa..8fc80b9a4 100644 --- a/common/vision/lasr_face_recognition/setup.py +++ b/common/vision/lasr_vision_deepface/setup.py @@ -4,8 +4,7 @@ from catkin_pkg.python_setup import generate_distutils_setup setup_args = generate_distutils_setup( - packages=['lasr_face_recognition'], - package_dir={'': 'src'} + packages=["lasr_vision_deepface"], package_dir={"": "src"} ) -setup(**setup_args) \ No newline at end of file +setup(**setup_args) diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py b/common/vision/lasr_vision_deepface/src/lasr_vision_deepface/__init__.py similarity index 100% rename from common/vision/lasr_face_recognition/src/lasr_face_recognition/__init__.py rename to common/vision/lasr_vision_deepface/src/lasr_vision_deepface/__init__.py diff --git a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py b/common/vision/lasr_vision_deepface/src/lasr_vision_deepface/deepface.py similarity index 96% rename from common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py rename to common/vision/lasr_vision_deepface/src/lasr_vision_deepface/deepface.py index 6fa062383..94c6568aa 100644 --- a/common/vision/lasr_face_recognition/src/lasr_face_recognition/deepface.py +++ b/common/vision/lasr_vision_deepface/src/lasr_vision_deepface/deepface.py @@ -10,7 +10,7 @@ from lasr_vision_msgs.srv import RecogniseRequest, RecogniseResponse DATASET_ROOT = os.path.join( - rospkg.RosPack().get_path("lasr_face_recognition"), "datasets" + rospkg.RosPack().get_path("lasr_vision_deepface"), "datasets" ) Mat = int # np.typing.NDArray[np.uint8]