Выполните калибровку изображения «рыбий глаз» — отмена эффекта «рыбий глаз»

В настоящее время я использую библиотеку opencv с c ++, и моя цель — отменить эффект «рыбий глаз» на изображении («сделать его плоскостью»)
Я использую функцию «undistortImage», чтобы отменить эффект, но мне нужно, прежде чем выполнить калибровку камеры, чтобы найти параметры K, Knew и D, но я не совсем понял документацию (ссылка: http://docs.opencv.org/master/db/d58/group__calib3d__fisheye.html#gga37375a2741e88052ce346884dfc9c6a0a0899eaa2f96d6eed9927c4b4f4464e05).
Насколько я понимаю, я должен дать два списка точек, и функция «калибровка» должна возвращать нужные мне массивы. Итак, мой вопрос заключается в следующем: учитывая изображение «рыбий глаз», как мне выбрать два списка точек, чтобы получить результат? На данный момент мой код, очень простой, просто делает снимок, отображает его, выполняет искажение и отображает новое изображение. Элементы в матрице являются случайными, поэтому в настоящее время результат не соответствует ожидаемому. Спасибо за ответы.

#include "opencv2\core\core.hpp"#include "opencv2\highgui\highgui.hpp"#include "opencv2\calib3d\calib3d.hpp"#include <stdio.h>
#include <iostream>using namespace std;
using namespace cv;

int main(){

cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
Mat image;
image = imread("C:/Users/Administrator/Downloads/eiffel.jpg", CV_LOAD_IMAGE_COLOR);   // Read the file
if (!image.data)                              // Check for invalid input
{
cout << "Could not open or find the image" << endl;
return -1;
}
cout << "Input image depth: " << image.depth() << endl;

namedWindow("Display window", WINDOW_AUTOSIZE);// Create a window for display.
imshow("Display window", image);                   // Show our image inside it.

Mat Ka = Mat::eye(3, 3, CV_64F); // Creating distortion matrix
Mat Da = Mat::ones(1, 4, CV_64F);
Mat dstImage(image.rows, image.cols, CV_32F);

cout << "K matrix depth: " << Ka.depth() << endl;
cout << "D matrix depth: " << Da.depth() << endl;

Mat Knew = Mat::eye(3, 3, CV_64F);
std::vector<cv::Vec3d> rvec;
std::vector<cv::Vec3d> tvec;
int flag = 0;
std::vector<Point3d> objectPoints1 = { Point3d(0,0,0),  Point3d(1,1,0),  Point3d(2,2,0), Point3d(3,3,0), Point3d(4,4,0), Point3d(5,5,0),
Point3d(6,6,0),  Point3d(7,7,0),  Point3d(3,0,0), Point3d(4,1,0), Point3d(5,2,0), Point3d(6,3,0), Point3d(7,4,0),  Point3d(8,5,0),  Point3d(5,4,0), Point3d(0,7,0), Point3d(9,7,0), Point3d(9,0,0), Point3d(4,3,0), Point3d(7,2,0)};
std::vector<Point2d> imagePoints1 = { Point(107,84),  Point(110,90),  Point(116,96), Point(126,107), Point(142,123), Point(168,147),
Point(202,173),  Point(232,192),  Point(135,69), Point(148,73), Point(165,81), Point(189,93), Point(219,112),  Point(248,133),  Point(166,119), Point(96,183), Point(270,174), Point(226,56), Point(144,102), Point(206,75) };

std::vector<std::vector<cv::Point2d> > imagePoints(1);
imagePoints[0] = imagePoints1;
std::vector<std::vector<cv::Point3d> > objectPoints(1);
objectPoints[0] = objectPoints1;
fisheye::calibrate(objectPoints, imagePoints, image.size(), Ka, Da, rvec, tvec, flag); // Calibration
cout << Ka<< endl;
cout << Da << endl;
fisheye::undistortImage(image, dstImage, Ka, Da, Knew); // Performing distortion
namedWindow("Display window 2", WINDOW_AUTOSIZE);// Create a window for display.
imshow("Display window 2", dstImage);                   // Show our image inside it.

waitKey(0);                                          // Wait for a keystroke in the window
return 0;
}

0

Решение

Для калибровки с cv::fisheye::calibrate Вы должны предоставить

objectPoints    vector of vectors of calibration pattern points in the calibration pattern coordinate space.

Это означает предоставить ИЗВЕСТНЫЕ реальные координаты точек (должны соответствовать точкам в imagePoints), но вы можете выбрать положение системы координат произвольно (но carthesian), так что вы должны знать свой объект — например, плоский тестовый шаблон.

imagePoints vector of vectors of the projections of calibration pattern points

Это должны быть те же точки, что и в objectPoints, но заданные в координатах изображения, поэтому, когда проекция точек объекта попадает на ваше изображение (считывание / извлечение координат из вашего изображения).

Например, если ваша камера захватила это изображение (взято из Вот ):

изображение testpattern, сделанное камерой «рыбий глаз»

Вы должны знать размер вашего тестового образца (с точностью до шкалы), например, вы можете выбрать верхний левый угол верхнего левого квадрата в качестве позиции (0,0,0), верхний правый угол верхнего левый квадрат равен (1,0,0), а левый нижний угол верхнего левого квадрата равен (1,1,0), поэтому весь ваш тестовый шаблон будет расположен на плоскости xy.

Тогда вы можете извлечь эти соответствия:

pixel        real-world
(144,103)    (4,3,0)
(206,75)     (7,2,0)
(109,151)    (2,5,0)
(253,159)    (8,6,0)

для этих точек (отмечены красным):

введите описание изображения здесь

Положение пикселя может быть вашим imagePoints список в то время как реальные позиции могут быть вашими objectPoints список.

Отвечает ли это на ваш вопрос?

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]