Jump to content
Compvision.ru

Штепсель

Пользователи
  • Content count

    5
  • Joined

  • Last visited

Everything posted by Штепсель

  1. Здравствуйте. Допустим, откалибровал камеру при разрешении 1280х1024, получил матрицу внутренних параметров и коэффициенты. Теперь, вывожу видео в разрешении 800х600. Документацию https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html читал. Поэтому несколько вопросов: 1. Насколько я понял, нужно маштабировать только матрицу внутренних параметров, не трогать коэффициенты? 2. Как маштабировать? Достаточно ли просто сделать fx` = fx * (w`/w) и аналогично для fy, где w` - новая ширина кадра, а w - ширина кадра, когда создавалась матрица. 3. Как потом быть с getOptimalNewCameraMatrix ? Подставлять в неё уже отмаштабированную матрицу? Или оригинальную, а потом маштабировать обе?
  2. Спасибо. Да, нужно менять ещё cx и cy, я думал достаточно только fx fy.
  3. Приветствую! Нужно с точностью хотя бы в десятые градуса найти поворот объекта относительно оригинала на изображении. Что бы исключить влияние вешней среды все изображения для опытов создаю в Blender`е (разумеется рендер с одинаковыми настройками и положением камеры, размер кадра 1600х1200). Из него же взял и cameraMatrix. На всякий случай так же пробовал в нём же рендерить шаблон шахматной доски под разными ракурсами, потом cameraCalibrate для получения cameraMatrix и distortionCoefficient в общем всё как по примерам OpenCV. Проверял perViewErrors - для каждого изображения доски в пределах 0.1-0.2 пикселя. Для начала рендерю изображение просто квадрата, который будет использоваться как оригинальный, под неким углом наклона камеры, в OpenCV нахожу положение 4 углов на изображении - imagePoints. Знаю, размер стороны квадрата и задаю координаты 3D точек, к примеру: std::vector<cv::Point3d> objectPoints; objectPoints.push_back(cv::Point3d(0.0f, 0.0f, 0.0f)); objectPoints.push_back(cv::Point3d(50.0f, 0.0f, 0.0f)); objectPoints.push_back(cv::Point3d(50.0f, 50.0f, 0.0f)); objectPoints.push_back(cv::Point3d(0.0f, 50.0f, 0.0f)); Дальше загоняю это в solvePnP: cv::solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs, rvec, tvec, false, cv::SOLVEPNP_ITERATIVE); Я правильно понимаю, что при расчёте все методы solvePnP исходят из того, что все 4 точки objectPoints то же должны оказаться лежащими на одной 3D плоскости? Я пытался вникнуть хотя бы в метод ITERATIVE, но трудновато. Получаю rvec, tvec. Пробовал разные методы (более лучший результат даёт AP3P). Теперь, я так понимаю, если применить rvec (точнее, получить матрицу трансформации из вектора сначала) и tvec к objectPoints я получу их 3D положение в системе координат камеры? А как быть, в случае, если точки imagePoints вычисляются с какими-либо погрешностями? К примеру, в 2-5 пикселей? Имею ввиду, что можно предпринять, что бы скорректировать результаты solvePnP до более правильных? Может увеличить количество точек до 5-6 ? Пробовал solve RANSAC, результат то же неоднозначный, но, возможно, нужно ещё больше точек? Может быть в сами координаты точек на изображение заложить какую-либо информацию? Имею ввиду, к примеру, угол между ними должен быть 90 градусов, либо расстояния определённые... В общем, ищется способ повышения точности rvec (в особенности) и tvec, когда уже невозможно точнее вычислить положение imagePoints. Либо какая-либо отдельная библиотека для solvePnP, что бы можно было задать дополнительные ограничения, из разряда - угол между 3D точками на плоскости после применения rvec и tvec должны быть 90 градусов и т.д.
  4. И снова здравствуйте. Поясните, пожалуйста, предназначение функции и где её использовать? getoptimalnewcameramatrix После прочтения документации по ссылке - как в анекдоте "дошло, но не понял". Что именно она делает, и чем эта матрица отличается от cameraMatrix, полученной из calibrateCamera ? Для каких вычислений она "оптимальная" ? Я правильно понимаю, что при обычной cameraMatrix после undistort из-за искажений, пиксели, которые не возможно "выправить" будут чёрными, а благодаря newCameraMatrix они всё же будут исправлены, но с большими ошибками? И её не стоит применять, если нужна точность вычислений, к примеру для solvePnP. Как можно получить через известную cameraMatrix прямоугольник cv::Rect, который бы соответствовал области, в которой ошибки будут минимальны?
×