Проблемы с кодом калибровки камеры ROS Noetic

Вопрос или проблема

У меня возникли проблемы с проектом калибровки камеры ROS уже некоторое время.

Я написал и скомпилировал C++ программу в ROS Noetic для распознавания шаблона шахматной доски для калибровки веб-камеры.

Программа написана так, что все сбор данных и обработка изображения происходят внутри исполняемого файла C++ с использованием VideoCapture cap(0) и imshow().
Программа не требует структуры узлов издателей и подписчиков для ввода, обработки и вывода кадров и матриц с веб-камеры.

Программа на C++ компилируется без ошибок. Однако, при запуске с помощью rosrun она выполняется бесконечно и, похоже, не может найти шахматные доски, не отображает никакие окна вывода и не выводит никаких завершенных матриц (или чего-либо, кроме пустой командной строки, дающей понять, что она работает). Единственные способы выйти из программы после ее запуска – либо закрыть окно командной строки, либо ввести команду kill.

Версии программного обеспечения:
Ubuntu 64-битная версия 20.04.4 LTS
Библиотека OpenCV2 версии 4.2.0
ROS noetic
CMake версия 3.16.3
GNU Make версия 4.2.1

Код на C++:

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/highgui.hpp>
#include <vector>
#include <iostream>


using namespace cv;
using namespace std;
 
 Mat frame,cropped_left_image,cropped_right_image,fullframe; 
 
     vector<Point2f> cornersRight; // это будет заполнено обнаруженными углами
     vector<Point2f> cornersLeft; // эти векторы хранят левые и правые угловые точки
     Point2f offset(0,432); // половина кадра 1280X720. Это значение задает смещение для корректировки координат
     
     const char* window_name4 = "Полный кадр";  
 


bool detectAndDrawLeftChessboardCorners()
{
    Size patternsize(8,6); // количество внутренних углов
    Mat gray; // Матрица для хранения изображения в градациях серого
    cvtColor(cropped_left_image,gray,COLOR_BGR2GRAY);// исходное изображение
     // это будет заполнено обнаруженными углами

    // CALIB_CB_FAST_CHECK экономит время на изображениях, которые не содержат углы шахматной доски
    bool patternfound = findChessboardCorners(gray, patternsize, cornersLeft,
                        CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
                        + CALIB_CB_FAST_CHECK); // найти углы шахматной доски и отправить их в левый угол

    if(patternfound)
        cornerSubPix(gray, cornersLeft, Size(11, 11), Size(-1, -1), 
            TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));

    drawChessboardCorners(cropped_left_image, patternsize, Mat(cornersLeft), patternfound);

    return true;
}

bool detectAndDrawRightChessboardCorners()
{
    Size patternsize(8,6); // количество внутренних углов
    Mat gray;
    cvtColor(cropped_right_image,gray,COLOR_BGR2GRAY);// исходное изображение
    // CALIB_CB_FAST_CHECK экономит время на изображениях, которые не содержат углы шахматной доски
    bool patternfound = findChessboardCorners(gray, patternsize, cornersRight,
                        CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE
                        + CALIB_CB_FAST_CHECK); // найти углы шахматной доски и отправить их в правый угол

    if(patternfound)
        cornerSubPix(gray, cornersRight, Size(11, 11), Size(-1, -1), 
            TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));

    drawChessboardCorners(cropped_right_image, patternsize, Mat(cornersRight), patternfound);

    return true;
}


void compensateRightOffset(){
    for(int i =0; i < cornersRight.size(); i++){ 
        cornersRight[i]+=offset;
    }
}


int main(int argc, char* argv[])
{
 
 VideoCapture cap(0);  // Открытие видео камеры по умолчанию (USB веб-камера)

 if (cap.isOpened() == false) // если не получилось, завершить программу
 {
  cout << "Не могу открыть видеокамеру" << endl;
  cin.get(); // ожидание нажатия любой клавиши
  return -1;
 } 

 double dWidth = cap.get(CAP_PROP_FRAME_WIDTH); 
 double dHeight = cap.get(CAP_PROP_FRAME_HEIGHT); 

 cout << "Разрешение видео: " << dWidth << " x " << dHeight << endl;


 while (true)
 {
  bool bSuccess = cap.read(frame); // считать новый кадр с видео 
  if (bSuccess == false) 
  {
   cout << "Видеокамера отключена" << endl;
   cin.get(); // Ожидание нажатия любой клавиши
   break;
  }
  
  cropped_left_image = frame(Range(0,(int)(dHeight)),Range(0,(0.6*dWidth)));
  detectAndDrawLeftChessboardCorners(); 

  cropped_right_image = frame(Range(0,dHeight),Range((0.4*dWidth),dWidth));
  detectAndDrawRightChessboardCorners(); 

  Mat cropped_left_full_display = cropped_left_image(Range(0,dHeight),Range(0,0.5*dWidth));
  Mat cropped_right_full_display = cropped_right_image(Range(0,dHeight),Range(128,0.5*dWidth));
 
  hconcat(cropped_left_full_display,cropped_right_full_display,fullframe);
  compensateRightOffset(); 
  
  imshow(window_name4, fullframe); 
 
  if (waitKey(10) == 27)
  {
   cout << "Клавиша Esc нажата пользователем. Остановка видео" << endl;
   break;
  }
 }

 return 0;

}

Я не понимаю, как такая ошибка может возникать в этой ситуации, и буду признателен за любую помощь с данной проблемой. Я не считаю, что это проблема с освещением, так как я тестировал эту программу в различных условиях окружающего освещения и получал тот же результат каждый раз.

Ответ или решение

Проблемы в коде калибровки камеры в ROS Noetic

Вы столкнулись с проблемами при калибровке камеры в ROS Noetic, и вашему коду C++ не удается обнаружить шахматную доску или выдавать ожидаемый результат. Давайте разберем этот код и выясним возможные причины его неправильного поведения.

1. Введение

Вы используете C++ программу для обработки видео с веб-камеры, используя библиотеку OpenCV для обнаружения шахматной доски и калибровки камеры. Вы отметили, что программа компилируется без ошибок, но при исполнении не показывает ожидаемых результатов — непрерывно работает, не показывает ни окон, ни матриц, и останавливается только при принудительном завершении.

2. Анализ кода

  1. Захват видео и открытие окна:

    VideoCapture cap(0);
    if (cap.isOpened() == false) {
        cout << "Cannot open the video camera" << endl;
        cin.get();
        return -1;
    }
    • Убедитесь, что ваша камера действительно подключена и устройство /dev/video0 доступно. В случае ошибки, вы должны увидеть выведенное сообщение "Cannot open the video camera".
  2. Проблемы с отображением окна:

    • Убедитесь, что функция imshow() вызывается корректно и окно имеет уникальное название. Название окна должно совпадать с именем в imshow(), например:
      const char* window_name4 = "Complete Frame";  
      imshow(window_name4, fullframe);
    • Попробуйте добавить waitKey(0) в случае, если окно закрывается слишком быстро.
  3. Обработка шахматной доски:

    • Убедитесь, что шахматная доска видна на изображениях и адаптируйте параметры функции findChessboardCorners(), например, размер паттерна и пороговые параметры, для улучшения точности обнаружения.
    • Попробуйте отключить CALIB_CB_FAST_CHECK, чтобы повлиять на поведение обнаружения:

      bool patternfound = findChessboardCorners(gray, patternsize, cornersLeft,
                        CALIB_CB_ADAPTIVE_THRESH +
                        CALIB_CB_NORMALIZE_IMAGE);
  4. Отладка и сообщения:

    • Рекомендуется внедрить сообщения для отладки после каждой основной операции для более точного определения местоположения проблемы. Это поможет уточнить, выполняется ли каждый шаг или где процесс замирает.

3. Рекомендации

  • Проверка оборудования: Убедитесь, что веб-камера исправно работает с другими приложениями и доступна через OpenCV.

  • Параметры OpenCV: Попробуйте протестировать другие параметры для findChessboardCorners() и cornerSubPix(). Иногда параметры одного окружения не являются оптимальными для другого.

  • Тестирование отдельных компонентов: Разбейте процесс на меньшие части и протестируйте независимо, чтобы выявить, какой этап не функционирует должным образом.

4. Заключение

Ваш код нуждается в отладке и улучшении для увеличения устойчивости и производительности. Основное внимание следует уделить корректной обработке видео, проверке условий использования OpenCV и адаптации параметров обнаружения. Регулярное использование выводов для отладки поможет значительно упростить процесс обнаружения проблем.

Если эти шаги не привели к решению вашей проблемы, обратитесь за поддержкой к внешним разработчикам или изучите дополнительную документацию по OpenCV и ROS Noetic для более глубокого понимания.

Оцените материал
Добавить комментарий

Капча загружается...