Я хочу рассчитать перспективное преобразование (матрицу для warpPerspective function), начиная с углов поворота и расстояния до объекта.
Как это сделать?
Я нашел код где-то на OE. Пример программы ниже:
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <math.h>
using namespace std;
using namespace cv;
Mat frame;
int alpha_int;
int dist_int;
int f_int;
double w;
double h;
double alpha;
double dist;
double f;
void redraw() {
alpha = (double)alpha_int/1000.;
//dist = 1./(dist_int+1);
//dist = dist_int+1;
dist = dist_int-50;
f = f_int+1;
cout << "alpha = " << alpha << endl;
cout << "dist = " << dist << endl;
cout << "f = " << f << endl;
// Projection 2D -> 3D matrix
Mat A1 = (Mat_<double>(4,3) <<
1, 0, -w/2,
0, 1, -h/2,
0, 0, 1,
0, 0, 1);
// Rotation matrices around the X axis
Mat R = (Mat_<double>(4, 4) <<
1, 0, 0, 0,
0, cos(alpha), -sin(alpha), 0,
0, sin(alpha), cos(alpha), 0,
0, 0, 0, 1);
// Translation matrix on the Z axis
Mat T = (Mat_<double>(4, 4) <<
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, dist,
0, 0, 0, 1);
// Camera Intrisecs matrix 3D -> 2D
Mat A2 = (Mat_<double>(3,4) <<
f, 0, w/2, 0,
0, f, h/2, 0,
0, 0, 1, 0);
Mat m = A2 * (T * (R * A1));
cout << "R=" << endl << R << endl;
cout << "A1=" << endl << A1 << endl;
cout << "R*A1=" << endl << (R*A1) << endl;
cout << "T=" << endl << T << endl;
cout << "T * (R * A1)=" << endl << (T * (R * A1)) << endl;
cout << "A2=" << endl << A2 << endl;
cout << "A2 * (T * (R * A1))=" << endl << (A2 * (T * (R * A1))) << endl;
cout << "m=" << endl << m << endl;
Mat frame1;
warpPerspective( frame, frame1, m, frame.size(), INTER_CUBIC | WARP_INVERSE_MAP);
imshow("Frame", frame);
imshow("Frame1", frame1);
}
void callback(int, void* ) {
redraw();
}
void main() {
frame = imread("FruitSample_small.png", CV_LOAD_IMAGE_COLOR);
imshow("Frame", frame);
w = frame.size().width;
h = frame.size().height;
createTrackbar("alpha", "Frame", &alpha_int, 100, &callback);
dist_int = 50;
createTrackbar("dist", "Frame", &dist_int, 100, &callback);
createTrackbar("f", "Frame", &f_int, 100, &callback);
redraw();
waitKey(-1);
}
Но, к сожалению, это преобразование делает что-то странное
Почему? Какая еще половина изображения выше, когда alpha>0
? И как вращаться вокруг других осей? Почему dist
работает так странно?