OpenCV Рисование в плоскости найденной метки .

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

OpenCV Рисование в плоскости найденной метки .

Сообщение Alex2013 » 25.06.2018 16:34:22

В общем образовался у меня некий "затык": Нужно нарисовать 2д элементы управления в той же плоскости, что и найденная метка но за её пределами Например виртуальную клавиатуру .
Рисование в пределах метки или просто с привязкой к метке понятное дело проблем не вызывает .
Есть два решения "в лоб" :
1 Просто взять и нарисовать 3д/2д-модель клавиатуры на заданном расстоянии (вычислив углы поворота и маштаб)
Изображение
2 Нарисовать клавиатур на "прозрачном" битмапе и вывести с афинными преобразованиями точно также как я вывожу на место метки 2д-катринку (разумеется чтобы нарисовать что-то за пределами метки нужно пропорционально увеличить масштаб найденного участка выполнив параллельный перенос точек )
Изображение

Но это как-то громоздко.....

По идее должны быть методы проще .
...и вроде бы есть ...
Код: Выделить всё
// Установите координаты на изображении маркера.
cvInitMatHeader (& image_points, 4, 1, CV_32FC2, src_pnt);

// Установите базовые координаты маркера
cvInitMatHeader (& object_points, 4, 3, CV_32FC1, baseMarkerPoints);

// Получите вращение и перевод из внутренних констант камеры (intrinstic и distortion)
cvFindExtrinsicCameraParams2 (& object_points, & image_points, внутреннее, искажение, вращение, перевод);

/ / Вычислить, в какую позицию, где координаты на реальном пространстве находятся на экране, используя результат
cvProjectPoints 2 (srcPoints3D, вращение, перевод, внутреннее, искажение, dstPoints2D);
В случае
// Нарисовать ось
Начальная точка CvPoint;
Конечная точка CvPoint;

startpoint = cvPoint ((int) dstPoints 2 D -> data.fl [0], (int) dstPoints 2 D -> data.fl [1]);
для (j = 1; j <4; j ++)
{
endpoint = cvPoint ((int) dstPoints 2 D -> data.fl [(j) * 3], (int) dstPoints 2 D -> data.fl [1+ (j) * 3]);
В случае
если (j == 1)
{
cvLine (изображение, начальная точка, конечная точка, CV_RGB (255, 0, 0), 2, 8, 0);
cvPutText (изображение, «X», конечная точка, & axisfont, CV_RGB (255, 0, 0));
}
если (j == 2)
{
cvLine (изображение, начальная точка, конечная точка, CV_RGB (0, 255, 0), 2, 8, 0);
cvPutText (изображение, «Y», конечная точка, & axisfont, CV_RGB (0, 255, 0));
}
если (j == 3)
{
cvLine (изображение, начальная точка, конечная точка, CV_RGB (0, 0, 255), 2, 8, 0);
cvPutText (изображение, «Z», конечная точка, & axisfont, CV_RGB (0, 0, 255));
}
}
// выводим номер маркера
cvPutText (изображение, текст, cvPoint ((int) (dstPoints 2 D -> data.fl [3] + dstPoints 2 D -> data.fl [6]) / 2,
(int) (dstPoints 2 D -> data.fl [4] + dstPoints 2 D -> data.fl [7]) / 2)
, & axisfont, CV_RGB (255, 255, 100));
}
}

}
}
}

Но как их использовать если cvFindExtrinsicCameraParams2 принципиально не работает по причине использования другого метода захвата кадров (не через OpenCV ) с камеры ? (или может я просто что-то не правильно понял ? (Коментарии гуглом приведены с японского ) )
Зы
Кроме того можно решить задачку из "школьной стереометрии" ...
1 Есть точки проекции метки "на экранную плоскость"
2 Размеры реальной метки известны .
Нужно сделать "обратный пересчет" получив точки "в 3д" относительно экрана и дорисовав что нужно в той-же плоскости вернуть обратно . (Все это безобразие сводится к пересчету "плоских координат", что в OpenCV стандартно и просто делается для картинки но не для точек и линий )


:idea: От первого "лобового" варианта отличается тем что это просто процедура преобразования координат 2д->2д без "лишних сущностей" ввиде ЗД модели и т.п.

В принципе это-то вариант уже работает но пока с искажениями - "изобретать велосипед" как всегда та еще морока.
Alex2013
энтузиаст
 
Сообщения: 964
Зарегистрирован: 03.04.2013 11:59:44

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

Рейтинг@Mail.ru