Birds Eye View / Homography using OpenCV
When I looked for a small example for a homography transformation using OpenCV in order to provide a birds eye projection of an image. I did not find an appropriate ones, hence, I combined a number of motivating introductions and code fragments in an illustrative small program. It can be adapted for your actual purpose or just use to determine the parameters of a perspective manually (for fast hacks :-), otherwise you should prefer one of the traditional calibration methods).

Compile with:
$ g++ example.cpp -o Example `pkg-config --libs --cflags opencv` -ldl
// ---------------------------------------------------------------------------
/* This code illustrates the capabilities of opencv related to bird eye view
* homography.
*
* The implementation extends the code presented by jmartel on
* http://stackoverflow.com/questions/6606891/opencv-virtually-camera-rotating-translating-for-birds-eye-view
*
* Take an additional view on
* https://en.wikipedia.org/wiki/Homography
*/
#include
#include
#define PI 3.14
using namespace cv;
int main( int argc, char** argv )
{
// read the camera input
VideoCapture cap(0);
if(!cap.isOpened())
return -1;
// default values of the homography parameters
int alpha_=90., beta_=90., gamma_=90.;
int f_ = 500, dist_ = 500;
// images
Mat destination;
Mat source;
/// Create Window
namedWindow("Result", 1);
/// Add trackbars for different aspects of the
createTrackbar("Alpha", "Result", &alpha_, 180);
createTrackbar("Beta", "Result", &beta_, 180);
createTrackbar("Gamma", "Result", &gamma_, 180);
createTrackbar("f", "Result", &f_, 2000);
createTrackbar("Distance", "Result", &dist_, 2000);
while(true) {
//grab and retrieve each frames of the video sequentially
cap >> source;
double f, dist;
double alpha, beta, gamma;
alpha = ((double)alpha_ - 90.)*PI/180;
beta = ((double)beta_ - 90.)*PI/180;
gamma = ((double)gamma_ - 90.)*PI/180;
f = (double) f_;
dist = (double) dist_;
Size taille = source.size();
double w = (double)taille.width, h = (double)taille.height;
// Projection 2D -> 3D matrix
Mat A1 = (Mat_(4,3) <<
1, 0, -w/2,
0, 1, -h/2,
0, 0, 0,
0, 0, 1);
// Rotation matrices around the X,Y,Z axis
Mat RX = (Mat_(4, 4) <<
1, 0, 0, 0,
0, cos(alpha), -sin(alpha), 0,
0, sin(alpha), cos(alpha), 0,
0, 0, 0, 1);
Mat RY = (Mat_(4, 4) <<
cos(beta), 0, -sin(beta), 0,
0, 1, 0, 0,
sin(beta), 0, cos(beta), 0,
0, 0, 0, 1);
Mat RZ = (Mat_(4, 4) <<
cos(gamma), -sin(gamma), 0, 0,
sin(gamma), cos(gamma), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
// Composed rotation matrix with (RX,RY,RZ)
Mat R = RX * RY * RZ;
// Translation matrix on the Z axis change dist will change the height
Mat T = (Mat_(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_(3,4) <<
f, 0, w/2, 0,
0, f, h/2, 0,
0, 0, 1, 0);
// Final and overall transformation matrix
Mat transfo = A2 * (T * (R * A1));
// Apply matrix transformation
warpPerspective(source, destination, transfo, taille, INTER_CUBIC | WARP_INVERSE_MAP);
// Output
imshow("Result", destination);
waitKey(30);
}
return 0;
}