📚
ROS Robotics Projects
  • Титульная страница
  • Термины
  • Глава 1. Начало работы с разработкой приложений ROS Robotics
    • Подглава 1.1 Начало работы с ROS
      • Подглава 1.1.1 Дистрибутивы ROS
      • Подглава 1.1.2 Поддерживаемые операционные системы
      • Подглава 1.1.3 Роботы и датчики, поддерживаемые ROS
      • Подглава 1.1.4 Почему ROS?
    • Подглава 1.2 Основы ROS
      • Подглава 1.2.1 Уровень файловой системы
      • Подглава 1.2.2 Уровень графов вычислений
      • Подглава 1.2.3 Уровень сообщества ROS
      • Подглава 1.2.4 Общение в ROS
    • Подглава 1.3 Клиентские библиотеки ROS
    • Подглава 1.4 Инструменты ROS
      • Подглава 1.4.1 Rviz (Визуализатор ROS)
      • Подглава 1.4.2 rqt_plot
      • Подглава 1.4.3 rqt_graph
    • Подглава 1.5 Симуляторы ROS
    • Подглава 1.6 Установка ROS kinetic на Ubuntu 16.04 LTS
      • Подглава 1.6.1 Начало работы с установкой
        • Подглава 1.6.1.1 Настройка репозиториев Ubuntu
        • Подглава 1.6.1.2 Настройка source.list
        • Подглава 1.6.1.3 Настройка ключей
        • Подглава 1.6.1.4 Установка ROS
        • Подглава 1.6.1.5 Инициализация rosdep
        • Подглава 1.6.1.6 Настройка среды ROS
        • Подглава 1.6.1.7 Получение rosinstall
    • Подглава 1.7 Настройка ROS на VirtualBox
    • Подглава 1.8 Настройка рабочего пространства ROS
    • Подглава 1.9 Возможности для ROS в отраслях и исследованиях
    • Подглава 1.10 Вопросы
    • Подглава 1.11 Заключение
  • Глава 2. Обнаружение и отслеживание лиц с использованием ROS, OpenCV и Dynamixel Servos
    • Подглава 2.1 Обзор проекта
    • Подглава 2.2 Аппаратные и программные предпосылки
      • Подглава 2.2.1 Установка зависимых пакетов ROS
        • Подглава 2.2.1.1 Установка пакета usb_cam ROS
          • Подглава 2.2.1.1.1 Создание рабочей области ROS для зависимостей
    • Подглава 2.3 Взаимодействие Dynamixel с ROS
      • Подглава 2.3.1 Установка пакетов ROS dynamicixel_motor
    • Подглава 2.4 Создание ROS-пакетов для трекера лица
      • Подглава 2.4.1 Интерфейс между ROS и OpenCV
    • Подглава 2.5 Работа с ROS-пакетом для отслеживания лиц
      • Подглава 2.5.1 Понимание кода трекера лица
      • Подглава 2.5.2 Понимание CMakeLists.txt
      • Подглава 2.5.3 Файл track.yaml
      • Подглава 2.5.4 Файлы запуска
      • Подглава 2.5.5 Запуск узла отслеживания лица
      • Подглава 2.5.6Пакет face_tracker_control
        • Подглава 2.5.6.1 Файл запуска start_dynamixel
        • Подглава 2.5.6.2 Файл запуска контроллера панорамирования
      • Подглава 2.5.7 Файл конфигурации контроллера панорамирования
      • Подглава 2.5.8 Файл конфигурации параметров сервосистемы
      • Подглава 2.5.9 Узел контроллера трекера лица
      • Подглава 2.5.10 Создание CMakeLists.txt
      • Подглава 2.5.11 Тестирование пакета управления трекером лица
      • Подглава 2.5.12 Соединение всех узлов вместе
      • Подглава 2.5.13 Закрепление кронштейна и настройка цепи
      • Подглава 2.5.14 Финальный запуск
    • Подглава 2.6 Вопросы
    • Подглава 2.7 Заключение
Powered by GitBook
On this page

Was this helpful?

  1. Глава 2. Обнаружение и отслеживание лиц с использованием ROS, OpenCV и Dynamixel Servos
  2. Подглава 2.5 Работа с ROS-пакетом для отслеживания лиц

Подглава 2.5.1 Понимание кода трекера лица

Давайте начнем с заголовочного файла. Заголовочные файлы ROS, которые мы используем в коде, находятся здесь. Мы должны включить ros/ros.h в каждый узел ROS C ++; в противном случае исходный код не будет компилироваться. Остальные три заголовка являются заголовками транспорта изображения, которые имеют функции для публикации и подписки на сообщения изображения с низкой пропускной способностью. Заголовок cv_bridge имеет функции для преобразования между типами данных OpenCV ROS. Заголовок image_encoding.h имеет формат кодирования изображения, используемый во время преобразования ROS-OpenCV:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

Следующий набор заголовков для OpenCV. Заголовок imgproc состоит из функций обработки изображений, highgui имеет функции, связанные с GUI, а objdetect.hpp имеет API для обнаружения объектов, такие как классификатор Haar:

#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/objdetect.hpp>

Последний заголовочный файл предназначен для доступа к пользовательскому сообщению с именем centroid. Определение сообщения центроида имеет два поля, int32x ,а также Int32 года, Он может держать центр тяжести файла. Вы можете проверить это определение сообщения из папки face_tracker_pkg/msg/centroid.msg:

#include <face_tracker_pkg/centroid.h>

Следующие строки кода дают имя окну необработанного изображения и окну обнаружения лица:

static const std::string OPENCV_WINDOW = "raw_image_window"; 
static const std::string OPENCV_WINDOW_1 = "face_detector";

Следующие строки кода создают класс C ++ для нашего детектора лиц. Фрагмент кода создает дескрипторы NodeHandle, который является обязательным дескриптором для узла ROS; image_transport, который помогает отправлять сообщения ROS Image по графу вычислений ROS; и издатель для лицевого центроида, который может публиковать значения центроидов, используя определенный нами файл centroid.msg. Остальные определения предназначены для обработки значений параметров из файла параметров track.yaml:

class Face_Detector{
ros::NodeHandle nh_; 
image_transport::ImageTransport it_; 
image_transport::Subscriber image_sub_; 
image_transport::Publisher image_pub_; 
ros::Publisher face_centroid_pub; 
face_tracker_pkg::centroid face_centroid;string input_image_topic, output_image_topic, haar_file_face;
int face_tracking, display_original_image, display_tracking_image, center_offset, screenmaxx;
}

Ниже приведен код для извлечения параметров ROS из файла track.yaml. Преимущество использования параметров ROS состоит в том, что мы можем избежать жесткого кодирования этих значений внутри программы и изменять значения без перекомпиляции кода:

try{
nh_.getParam("image_input_topic", input_image_topic); nh_.getParam("face_detected_image_topic", output_image_topic); nh_.getParam("haar_file_face", haar_file_face); nh_.getParam("face_tracking", face_tracking); nh_.getParam("display_original_image", display_original_image); nh_.getParam("display_tracking_image", display_tracking_image); nh_.getParam("center_offset", center_offset); nh_.getParam("screenmaxx", screenmaxx);
ROS_INFO("Successfully Loaded tracking parameters");
}

Следующий код создает подписчика для topic входного изображения и издателя для изображения с обнаруженным лицом. Всякий раз, когда изображение попадает в topic входного изображения, оно вызывает функцию imageCb. Названия тем извлекаются из параметров ROS. Мы создаем другого издателя для публикации значения центроида, который является последней строкой фрагмента кода:

image_sub_ = it_.subscribe(input_image_topic, 1, &Face_Detector::imageCb, this);
image_pub_ = it_.advertise(output_image_topic, 1);
face_centroid_pub = nh_.advertise<face_tracker_pkg::centroid> ("/face_centroid",10);

Следующий фрагмент кода - это определение imageCb, который является обратным вызовом для input_image_topic, что он в основном делает, это конвертирует sensor_msgs/Image данные в cv::Mat Тип данных OpenCV. cv_bridge::CvImagePtr cv_ptr буфер выделяется для хранения образа OpenCV после выполнения преобразования ROS-OpenCV с использованием функции cv_bridge::toCvCopy:

void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
namespace enc = sensor_msgs::image_encodings;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
//Мы уже обсуждали классификатор Хаара; Вот код для загрузки файла классификатора Хаара:
string cascadeName = haar_file_face; CascadeClassifier cascade;
if( !cascade.load( cascadeName ) )
{
cerr << "ERROR: Could not load classifier cascade" << endl;
}

Теперь мы переходим к основной части программы, которая заключается в обнаружении лица, выполненного для преобразованного типа данных изображения OpenCV, из сообщения ROS Image. Ниже приведен вызов функции detectAndDraw(), который выполняет обнаружение лица, и в последней строке вы можете увидеть опубликованную в topic выходного изображения. С помощью

cv_ptr->image мы можем получить cv::Mat тип данных, и в следующей строке,

cv_ptr->toImageMsg() может преобразовать это в ROSImage. Аргументы функции

detectAndDraw() - это изображение OpenCV и каскадные переменные:

detectAndDraw( cv_ptr->image, cascade ); image_pub_.publish(cv_ptr->toImageMsg());

Mat gray, smallImg;
cvtColor( img, gray, COLOR_BGR2GRAY ); double fx = 1 / scale ;
resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR ); 
equalizeHist( smallImg, smallImg );
t = (double)cvGetTickCount(); cascade.detectMultiScale( smallImg, faces, 1.1, 15, 0 |CASCADE_SCALE_IMAGE, Size(30, 30) );

Следующий цикл будет повторяться для каждого лица, обнаруженного с помощью функции detectMultiScale(). Для каждого лица он находит центроид и публикует /face_centroid topic:

for ( size_t i = 0; i < faces.size(); i++ )
{
Rect r = faces[i]; Mat smallImgROI;
vector<Rect> nestedObjects; Point center;
Scalar color = colors[i%8]; int radius;
double aspect_ratio = (double)r.width/r.height; if( 0.75 < aspect_ratio && aspect_ratio < 1.3 )
{
center.x = cvRound((r.x + r.width*0.5)*scale);
center.y = cvRound((r.y + r.height*0.5)*scale); 
radius = cvRound((r.width + r.height)*0.25*scale); 
circle( img, center, radius, color, 3, 8, 0 );
face_centroid.x = center.x; face_centroid.y = center.y;
// Публикация центроида обнаруженного лица 
face_centroid_pub.publish (face_centroid);
}

Чтобы сделать окно выходного изображения более интерактивным, есть текст и строки для оповещения о лице пользователя слева или справа или в центре. Этот последний раздел кода в основном для этой цели. Для этого используется API OpenCV. Вот код для отображения текста, такого как Левый, Правый и Центр, на экране:

putText(img, "Left", cvPoint(50,240), FONT_HERSHEY_SIMPLEX, 1,cvScalar(255,0,0), 2, CV_AA);
putText(img, "Center", cvPoint(280,240), FONT_HERSHEY_SIMPLEX, 1, cvScalar(0,0,255), 2, CV_AA);
putText(img, "Right", cvPoint(480,240), FONT_HERSHEY_SIMPLEX, 1, cvScalar(255,0,0), 2, CV_AA);

Отлично! Мы закончили с кодом трекера; давайте посмотрим, как его собрать и сделать его исполняемым.

PreviousПодглава 2.5 Работа с ROS-пакетом для отслеживания лицNextПодглава 2.5.2 Понимание CMakeLists.txt

Last updated 5 years ago

Was this helpful?

Давайте разберемся c функцией detectAndDraw(), которая взята из примера кода OpenCV для обнаружения лица: аргументами функции являются входное изображение и каскадный объект. Следующий фрагмент кода сначала преобразует изображение в градации серого и выровняет гистограмму с помощью API-интерфейсов OpenCV. Это своего рода предварительная обработка перед обнаружением лица по изображению. Для этого используется функция cascade.detectMultiScale() ().

http://docs.opencv.org/2.4/modules/objdetect/doc/cascade_classification.html