Проекция 3D-круга на 2D-изображение с камеры

Спросил об этом на math.stackexchange, но ответов нет, поэтому пытаюсь здесь, надеюсь, люди, занимающиеся компьютерным зрением, смогут помочь.

Предположим, что у меня есть трехмерный круг с центром в (c1, c2, c3) в системе координат круга C. Радиус круга равен r, и есть единичный вектор (v1, v2, v3) (также в системе координат C), перпендикулярный плоскости круга в центральной точке.

У меня есть камера-обскура, расположенная в точке (k1, k2, k3) в системе координат камеры K. У меня есть известная матрица преобразования системы координат камеры в круг kTc, которая преобразует любую точку в C в систему координат K, так что point_k = np.dot(kTc, point_c), где point_k — точка в системе координат K, а point_c — точка в системе координат C. Камера имеет известную встроенную матрицу камеры I.

Как спроецировать 3D-круг на плоскость изображения камеры?

В идеале хотелось бы сделать это на питоне.

Я рекомендую посмотреть этот вопрос и ответы на него на Gamedev: gamedev.stackexchange.com/questions/188076/…

Simon Lundberg 03.02.2023 23:02

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

Paritosh Kulkarni 13.02.2023 08:22
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
126
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы хотите использовать модуль scipy вместе с numpy. Задача, которую вы решаете, — это преобразование сферы в 2D-плоскость, а затем преобразование этой плоскости (посредством вращения и смещения) в плоскость камеры (какой бы она ни была).

Во-первых, здесь отсутствует некоторая информация о плоскости камеры (фи и/или тета относительно начала координат) или уравнение плоскости и сферы (уравнение сферы в радиальных координатах). Преобразования были бы немного сложными без информации об уравнениях, углах и плоскостях. Я согласен, что вы дали информацию в переменных, но было бы легко иметь под рукой уравнения ИЛИ первым шагом было бы создание уравнений (выполнение этого вручную или с использованием математики и т. д.)

Я буду использовать эту документацию, чтобы попытаться ответить на ваш вопрос - https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.transform.Rotation.html

Ниже приведен псевдокод

не пытайтесь выполнить его как есть

import numpy as np
from scipy.spatial.transform import Rotation

# Define the center of the circle in the circle coordinate frame
c = np.array([c1, c2, c3])

# Define the normal vector of the circle in the circle coordinate frame
n = np.array([v1, v2, v3])

# Define the camera center in the camera coordinate frame
k = np.array([k1, k2, k3])

# Define the intrinsic camera matrix
I = np.array(..., dtype=np.float32)

# Define the rotation matrix part of kTc
R = np.array(..., dtype=np.float32)

# Define the translation vector part of kTc
t = np.array(..., dtype=np.float32)

# Convert R to a scipy Rotation object
R_obj = Rotation.from_dcm(R)

# Transform the center of the circle to the camera coordinate frame
c_k = R_obj.apply(c) + t

# Project the center of the circle onto the image plane
c_p = I @ c_k

# Normalize the center projection by dividing by its third component
c_p = c_p[:2] / c_p[2]

# Transform the normal vector to the camera coordinate frame
n_k = R_obj.apply(n)

# Project the normal vector onto the image plane
n_p = I[:2, :3] @ n_k

# Normalize the normal projection by dividing by its third component
n_p = n_p / n_p[2]

# Calculate the equation of the circle in the image plane
r_squared = r**2 - np.sum(n_p[:2]**2) / n_p[2]**2

А вот объяснение уравнений, используемых в коде:

c = np.array([c1, c2, c3]): The center of the circle in the circle coordinate frame is represented by the vector c = [c1, c2, c3].
n = np.array([v1, v2, v3]): The normal vector of the circle in the circle coordinate frame is represented by the vector n = [v1, v2, v3].
k = np.array([k1, k2, k3]): The camera center in the camera coordinate frame is represented by the vector k = [k1, k2, k3].
I = np.array(..., dtype=np.float32): The intrinsic camera matrix is represented by the 2D array I.
R = np.array(..., dtype=np.float32): The rotation matrix part of the kTc transformation matrix is represented by the 3x3 array R.
t = np.array(..., dtype=np.float32): The translation vector part

Алгоритм ответа:

Чтобы спроецировать 3D-круг на плоскость изображения камеры, вам необходимо выполнить следующие действия:

  1. Преобразуйте трехмерный круг из системы координат круга (C) в систему координат камеры (K), используя матрицу преобразования kTc. Центр преобразованного круга будет задан:

    center_k = np.dot (kTc, [c1, c2, c3, 1])

  2. Спроецируйте центр преобразованного круга на плоскость изображения камеры, используя внутреннюю матрицу камеры I. Проекция центра будет определяться как:

    center_p = np.dot (I, center_k)

  3. Преобразуйте вектор нормали из системы координат круга (C) в систему координат камеры (K), используя матрицу преобразования kTc. Преобразованный вектор нормали будет иметь вид:

    normal_k = np.dot(kTc[:3, ​​:3], [v1, v2, v3])

  4. Спроецируйте преобразованный вектор нормали на плоскость изображения камеры, используя внутреннюю матрицу камеры I. Проекция вектора нормали будет иметь вид:

    normal_p = np.dot(I[:2,:3], normal_k)

  5. Теперь, используя центральную и нормальную проекции, вы можете найти уравнение 2D-окружности в плоскости изображения камеры. Уравнение окружности в плоскости изображения будет иметь вид:

    (x - center_p[0]/center_p[2])^2 + (y - center_p[1]/center_p[2])^2 = r^2 - (normal_p[0]^2 + normal_p[1]^2 )/(нормаль_р[2]^2)

где (x, y) — координаты плоскости изображения проецируемого круга.

Обратите внимание, что вам нужно будет нормализовать центральную и нормальную проекции, разделив каждую на их соответствующие третьи компоненты (center_p[2] и normal_p[2]), чтобы получить их фактические координаты плоскости изображения.

Другие вопросы по теме