найти отображение между точкой видео и точкой реального мира - PullRequest
4 голосов
/ 12 мая 2019

Я занимаюсь отслеживанием автомобилей на видео Я пытаюсь определить, сколько метров он преодолел.

Я случайно вытянул 7 точек из видеокадра. Я сделал point1 своим происхождением

Затем в соответствующей перспективе Google Maps я вычислил расстояния 6 точек от оргина (дельта х и дельта у)

Затем я запустил следующее

pts_src = np.array([[417, 285], [457, 794], [1383, 786], [1557, 423], [1132, 296], [759, 270], [694, 324]])

pts_dst = np.array([[0,0], [-3, -31], [30, -27], [34, 8], [17, 15], [8, 7], [6, 1]])

h, status = cv2.findHomography(pts_src, pts_dst)

a = np.array([[1032, 268]], dtype='float32')
a = np.array([a])

# finally, get the mapping
pointsOut = cv2.perspectiveTransform(a, h)

Когда я проверял сопоставление пункта 7, результаты были неправильными.

Я что-то упустил? Или я использую неправильный метод? Спасибо

Вот изображение с видео enter image description here

Я отметил точки, и вот отображение enter image description here

Столбец x, y представляет пиксели на изображении. Отмеренный столбец представляет расстояние от начала координат до точки в метрах. Я в основном, используя карты Google, преобразовал геокод в UTM и рассчитал разницу x и y.

Я попытался ввести седьмую точку, и я получил [[[14.682752 9.927497]]] как вывод, который находится довольно далеко по оси x.

Есть идеи, если я делаю что-то не так?

1 Ответ

4 голосов
/ 13 мая 2019

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

Для камер с небольшим углом обзора результат довольно близок, но для камеры «рыбий глаз» результат может быть очень плох.1003 *

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

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

РЕДАКТИРОВАТЬ

В вашем случае я бы сказал, что проблема заключается во входных данных: учитывая квазиквадратичный элемент, образованный точками 6, 3, 1, 2

image with marked quasi-quadrilateral

Если расстояние АД в метрах составляет 36,9, как расстояние БК может составлять 53,8 метра?

Может быть, проблема в том, как вы собрали данные, иличто карты Google не следует считать надежными для таких небольших измерений.

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

РЕДАКТИРОВАТЬ

Для проверки я написал простой нелинейный решатель наименьших квадратов (работы по стохастическому восхождению на холм), используя изображение моего пола дляПопробуй это.Через несколько секунд (он написан на Python, так что скорость это не лучшая функция) может решить общее точное уравнение плоской камеры:

 pixel_x = (world_x*m11 + world_y*m12 + m13) / w
 pixel_y = (world_x*m21 + world_y*m22 + m23) / w
 w = (x*m31 + y*m32 + m33)

 m11**2 + m12**2 + m13**2 = 1

, и я могу получить камеру с максимальной ошибкой менее 4 пикселей (на изображении 4k).

enter image description here

С данными YOUR , однако я не могу получить ошибку менее 120 пикселей.Лучшая матрица, которую я нашел для ваших данных:

0.0704790534896005     -0.0066904288370295524   0.9974908226049937
0.013902632209214609   -0.03214426521221147     0.6680756144949469
6.142954035443663e-06  -7.361135651590592e-06   0.002007213927080277

Решая ваши данные, используя только точки 1, 2, 3 и 6, я, конечно, получаю точное числовое решение (с четырьмя общими точками есть один точный планарныйкамера) но изображение явно совершенно неправильное (сетка должна лежать на уличной плоскости):

enter image description here

...