OpenCV: угол CvBox2D

0

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

Говорят, что угол окна - это угол между горизонтальной осью и первой стороной (т.е. Длина), но результаты, которые я получаю, несколько странные.

  • Ангел равен 180 °, если моя голова направлена вверх.
  • Когда я наклоняюсь вправо, угол уменьшается примерно до 135 °, а затем внезапно скачет примерно до 315 °.
  • Когда я наклоняюсь влево, угол поднимается до 260 ° без каких-либо странных изменений.

Здесь короткое видео: угол cvBox2D

Любая идея, что происходит и как я могу рассчитать угол наклона?

И вот мой код:

  CvBox2D box;
  CvPoint center;
  CvSize size;
  int count = largest_contour->total;

  CvMat* points_f = cvCreateMat( 1, count, CV_32FC2 );
  CvMat points_i = cvMat( 1, count, CV_32SC2, points_f->data.ptr );
  cvCvtSeqToArray(largest_contour, points_f->data.ptr, CV_WHOLE_SEQ );
  cvConvert( &points_i, points_f );

  box = cvFitEllipse2(points_f);
  center = cvPointFrom32f(box.center);
  size.width = cvRound(box.size.width*0.5);
  size.height = cvRound(box.size.height*0.5);

  cvEllipse(dst,center,size,box.angle,0,360,cvScalar(0,255,0),2,8,0); 

  float newAngle = (box.angle > 90 ? 180 - box.angle : -1*(box.angle));
  • 0
    315-135 = 180, поэтому можно предположить, что вы вычисляете функцию арктана где-то с 1 параметром y / x. Есть ли 2-параметрическая функция arctan, которую вы можете использовать вместо нее, которая принимает координаты x и y, что позволяет избежать этой присущей неопределенности на 180 градусов?
  • 0
    @Matt Я нигде не использую функцию arctan. Источник cvFitEllipse2 имеет это где-то, чтобы вычислить угол эллипса. Я проверил исходный код, и есть два алгоритма, оба выполняют некоторые вычисления арктана для угла, и я не понимаю, что на самом деле там происходит. Но вы правы, это неопределенность на 180 °.
Теги:
opencv
angle
ellipse

2 ответа

1
Лучший ответ

Итак, я нашел ответ на свою проблему.

Если вы посмотрите на исходный код для функции cvFitEllipse2, которую вы можете найти в... \modules\imgproc\src файле: "shapeescr.cpp", вы увидите, что для выполнения эллипса есть два разных алгоритма. По умолчанию только один используется в версии openCV231, которую я использую.

icvFitEllipse_F - это функция, которая вызвала мою проблему, но есть также часть алгоритма, которая не используется, потому что следующий код находится в коде функции cvFitEllipse2:

#if 1
    icvFitEllipse_F( ptseq, &box );
#else
/*
 *  New fitellipse algorithm, contributed by Dr. Daniel Weiss
 */

поэтому новый алгоритм фитильпеля не компилируется.

Изменяя #if 1 на #if 0, другой алгоритм компилируется и используется вместо icvFitEllipse_F, и теперь все работает отлично.

0

Я использую отслеживание CAMShift в нескольких приложениях отслеживания заголовков с приведенным ниже вычислением после простого изменения демо-версии CAMShift от OpenCV:

float newAngle = (trackBox.angle> 90? 180 - trackBox.angle: -1 * (trackBox.angle));

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

  • 0
    То, что вы написали, находится на правильном пути. Насколько я вижу, угол, который дает cvFitEllipse2, находится между осью y (которая имеет "южное" направление) и длинной осью эллипса. Так что ваш новый угол даст мне именно то, что я нужно для отслеживания головы. +/- угол крена. Проблема в том, что неопределенность 180 ° все еще там. Как сказал Мэтт из вычислений арктана, но это делается внутри cvFitEllipse2. Это происходит в двух местах, когда угол равен 45 ° и когда это -135 ° (это углы после добавления вашего кода). Я обновил видео, чтобы вы могли увидеть, что я имею в виду, и добавил свой код. Надеюсь, вы можете помочь.
  • 0
    Я также проверил источник CamShift и не вижу никаких звонков на fitEllipse. Но он вычисляет угол прямоугольника и возвращает его как box.angle. Я добавил выше в своем посте манипуляции с углами, сделанные в CamShift и cvFitEllipse2. Может быть, вы можете понять это.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню