diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..042e9d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.cache
+build
+devel
+cmake-build-*
+.catkin_workspace
+/src/CMakeLists.txt
diff --git a/README.md b/README.md
index e69de29..d1cd988 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,21 @@
+# 光珀项目感知算法
+
+
+## 功能包guangpo_yolo
+
+使用rk3588运行yolov5,订阅图像数据,识别电梯
+再根据识别到的人和电梯,得到电梯的拥挤度
+
+具体拥挤度原理:
+识别电梯和人后,根据高度进行单目深度估计
+根据估计到的深度和相机内参得到相机坐标系下的3d位置
+然后电梯和人距离在一定范围内,可以认定有关联
+
+
+## 功能包image_saver
+订阅图像数据,生成图片,方便录制数据包后标定数据
+
+配置文件在对应包路径下的yaml_config/yaml_config.yaml文件中,可以配置:
+1. 订阅的话题
+2. 间隔多少帧生成一张图片
+3. 生成文件的保存路径
diff --git a/src/image_saver/.gitignore b/src/image_saver/.gitignore
new file mode 100644
index 0000000..15b9005
--- /dev/null
+++ b/src/image_saver/.gitignore
@@ -0,0 +1,2 @@
+/images
+images.*
diff --git a/src/image_saver/CMakeLists.txt b/src/image_saver/CMakeLists.txt
new file mode 100644
index 0000000..b7ce92a
--- /dev/null
+++ b/src/image_saver/CMakeLists.txt
@@ -0,0 +1,217 @@
+cmake_minimum_required(VERSION 3.0.2)
+project(image_saver)
+
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+## 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
+ cv_bridge
+ roscpp
+ sensor_msgs
+)
+
+
+find_package(yaml-cpp REQUIRED)
+find_package(OpenCV REQUIRED)
+
+## 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()
+
+################################################
+## 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
+# sensor_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 image_saver
+# CATKIN_DEPENDS cv_bridge roscpp sensor_msgs
+# 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}
+ yaml_config
+)
+
+## Declare a C++ library
+# add_library(${PROJECT_NAME}
+# src/${PROJECT_NAME}/image_saver.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/main.cc yaml_config/yaml_config.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}
+ ${OpenCV_LIBS}
+ yaml-cpp
+)
+
+#############
+## 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
+# scripts/my_python_script
+# 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_image_saver.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/src/image_saver/launch/run.launch b/src/image_saver/launch/run.launch
new file mode 100644
index 0000000..3b88f8f
--- /dev/null
+++ b/src/image_saver/launch/run.launch
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/image_saver/package.xml b/src/image_saver/package.xml
new file mode 100644
index 0000000..b76bb63
--- /dev/null
+++ b/src/image_saver/package.xml
@@ -0,0 +1,68 @@
+
+
+ image_saver
+ 0.0.0
+ The image_saver package
+
+
+
+
+ ubuntu
+
+
+
+
+
+ TODO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ catkin
+ cv_bridge
+ roscpp
+ sensor_msgs
+ cv_bridge
+ roscpp
+ sensor_msgs
+ cv_bridge
+ roscpp
+ sensor_msgs
+
+
+
+
+
+
+
+
diff --git a/src/image_saver/src/main.cc b/src/image_saver/src/main.cc
new file mode 100644
index 0000000..7f2ba15
--- /dev/null
+++ b/src/image_saver/src/main.cc
@@ -0,0 +1,85 @@
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "yaml_config.h"
+
+class ImageSaver {
+ public:
+ ImageSaver(ros::NodeHandle& nh) {
+ std::string subscribe_topic =
+ yaml_config["sub_image_topic"].as();
+ std::cout << "subscribe_topic=" << subscribe_topic << std::endl;
+ // 订阅图像话题
+ image_sub_ =
+ nh.subscribe(subscribe_topic, 1, &ImageSaver::imageCallback, this);
+
+ // 设置保存图像的路径
+ save_path_ = yaml_config["save_path"].as();
+ if (save_path_.empty()) {
+ std::filesystem::path current_dir =
+ std::filesystem::path(__FILE__).parent_path().parent_path();
+ std::filesystem::path yaml_path = current_dir / "images";
+ save_path_ = yaml_path;
+ if (!std::filesystem::exists(yaml_path)) {
+ if (std::filesystem::create_directory(yaml_path)) {
+ std::cout << "Created directory: " << yaml_path << std::endl;
+ } else {
+ std::cerr << "Failed to create directory: " << yaml_path << std::endl;
+ std::terminate();
+ }
+ }
+ }
+ std::cout << "save_path=" << save_path_ << std::endl;
+ frame_count_ = 0;
+
+ save_interval_ = yaml_config["save_interval"].as();
+ std::cout << "save_interval=" << save_interval_ << std::endl;
+ }
+
+ void imageCallback(const sensor_msgs::ImageConstPtr& msg) {
+ // 每3帧保存一张图像
+ if (frame_count_ % save_interval_ == 0) {
+ cv_bridge::CvImagePtr cv_ptr;
+ try {
+ cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
+ } catch (cv_bridge::Exception& e) {
+ ROS_ERROR("cv_bridge exception: %s", e.what());
+ return;
+ }
+
+ // 保存图像
+ std::string file_name =
+ save_path_ + "/" + "image_" + std::to_string(save_count_) + ".jpg";
+ cv::imwrite(file_name, cv_ptr->image);
+ save_count_++;
+ ROS_INFO("Saved image: %s", file_name.c_str());
+ }
+
+ frame_count_++;
+ }
+
+ private:
+ ros::Subscriber image_sub_;
+ std::string save_path_;
+ int frame_count_;
+ int save_count_ = 0;
+ int save_interval_;
+};
+
+int main(int argc, char** argv) {
+ ros::init(argc, argv, "image_saver");
+ ros::NodeHandle nh;
+
+ ImageSaver image_saver(nh);
+
+ ros::spin();
+
+ return 0;
+}
diff --git a/src/image_saver/yaml_config/yaml_config.cpp b/src/image_saver/yaml_config/yaml_config.cpp
new file mode 100644
index 0000000..8cf1661
--- /dev/null
+++ b/src/image_saver/yaml_config/yaml_config.cpp
@@ -0,0 +1,100 @@
+#include "yaml_config.h"
+#include
+#include
+
+YAML::Node ReadConfigYamlFile();
+
+// static std::string yaml_config_path =
+// "/media/Projects/guangpo_lidar/src/guangpo_lidar/yaml_config/yaml_config.yaml";
+static std::string yaml_config_path = []()->std::string{
+ std::filesystem::path current_dir =
+ std::filesystem::path(__FILE__).parent_path();
+ std::filesystem::path yaml_path = current_dir / "yaml_config.yaml";
+ std::cout << "yaml file path: " << yaml_path << std::endl;
+ return yaml_path;
+}();
+
+YAML::Node yaml_config = ReadConfigYamlFile();
+
+YAML::Node ReadConfigYamlFile() {
+ YAML::Node res;
+
+ std::cout << __PRETTY_FUNCTION__ << ": " << std::endl;
+ std::cout << "BEGIN READ FILE: " << yaml_config_path << std::endl;
+ bool read_successful_flag = false;
+ try {
+ // Load the YAML file
+ res = YAML::LoadFile(yaml_config_path);
+ read_successful_flag = true;
+ } catch (const YAML::Exception &e) {
+ std::cerr << "Error while reading the YAML file: " << yaml_config_path
+ << e.what() << std::endl;
+ // gDebugError("[GXT] : Error while reading the YAML file:") << e.what();
+ }
+ if (!read_successful_flag) {
+ // std::cerr << "backtrace:" << __PRETTY_FUNCTION__ << std::endl;
+ // std::cerr << "backtrace:" << __PRETTY_FUNCTION__ << std::endl;
+ // std::cerr << "backtrace:" << __PRETTY_FUNCTION__ << std::endl;
+ std::cerr << "Error while reading the YAML file!" << yaml_config_path
+ << std::endl;
+ std::cerr << "Error while reading the YAML file!" << yaml_config_path
+ << std::endl;
+ std::cerr << "Error while reading the YAML file!" << yaml_config_path
+ << std::endl;
+ std::terminate();
+ }
+ std::cout << "Read yaml config file successfully! " << yaml_config_path
+ << std::endl;
+ return res;
+}
+
+// __attribute((constructor)) inline bool
+// GxtReadConfigYamlFile(const std::string &yaml_config_path) {
+// bool read_successful_flag = false;
+// try {
+// // Load the YAML file
+// YAML::Node config = YAML::LoadFile(yaml_config_path);
+//
+// read_successful_flag = true;
+// // gDebugCol1("READ CONFIG FILE SUCCESSFULLY!");
+//
+// auto quantize = config["quantize"];
+// ADDCONFIG(quantize, quantize_pose_quaternion_bit_width);
+// ADDCONFIG(quantize, quantize_pose_quaternion_il);
+// ADDCONFIG(quantize, quantize_pose_quaternion_bit_width);
+// ADDCONFIG(quantize, quantize_pose_quaternion_il);
+//
+// ADDCONFIG(quantize, quantize_imu_speed_bit_width);
+// ADDCONFIG(quantize, quantize_imu_speed_il);
+// ADDCONFIG(quantize, quantize_imu_accbias_bit_width);
+// ADDCONFIG(quantize, quantize_imu_accbias_il);
+// ADDCONFIG(quantize, quantize_imu_gyrobias_bit_width);
+// ADDCONFIG(quantize, quantize_imu_gyrobias_il);
+//
+// ADDCONFIG(quantize, quantize_inverse_depth_bit_width);
+// ADDCONFIG(quantize, quantize_inverse_depth_il);
+//
+// ADDCONFIG(quantize, quantize_hessian_bit_width);
+// ADDCONFIG(quantize, quantize_hessian_il);
+// ADDCONFIG(quantize, quantize_b_bit_width);
+// ADDCONFIG(quantize, quantize_b_il);
+//
+// auto flag = config["flag"];
+// ADDCONFIG(flag, use_gxt_backend);
+// ADDCONFIG(flag, enable_quantize);
+// } catch (const YAML::Exception &e) {
+// // std::cerr << "Error while reading the YAML file: " << e.what() <<
+// // std::endl;
+// gDebugError("[GXT] : Error while reading the YAML file:") << e.what();
+// }
+//
+// if (!read_successful_flag) {
+// gDebugCol3("\n\n\n==========================================");
+// gDebugCol3("[GXT] : Error while reading the YAML file!");
+// gDebugCol3("[GXT] : Error while reading the YAML file!");
+// gDebugError("[GXT] : Error while reading the YAML file!");
+// std::terminate();
+// }
+//
+// return 0;
+// }
diff --git a/src/image_saver/yaml_config/yaml_config.h b/src/image_saver/yaml_config/yaml_config.h
new file mode 100644
index 0000000..0771ab6
--- /dev/null
+++ b/src/image_saver/yaml_config/yaml_config.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include
+
+#include
+
+
+extern YAML::Node yaml_config;
diff --git a/src/image_saver/yaml_config/yaml_config.yaml b/src/image_saver/yaml_config/yaml_config.yaml
new file mode 100644
index 0000000..4b9b1c5
--- /dev/null
+++ b/src/image_saver/yaml_config/yaml_config.yaml
@@ -0,0 +1,6 @@
+# 基础ros设置
+sub_image_topic : "/usb_cam/image_raw"
+# 每隔多少图片保存一张
+save_interval : 5
+# 保存图片路径:(为空则默认保存在这个功能包的images目录下)
+save_path : ""
\ No newline at end of file