OpenCV

Learning OpenCV

Calculating Fundamental Matrix

Posted by rmehran on February 5, 2008

Even though OpenCV Wiki states the following code as example for fundamental matrix calculation I made another code to work. There was an issue with different behaviors in cvFindFundamentalMat() and cvFindFundamentalMatrix() that I didn’t understand as well.

Lets’ look at the example code from Wiki

Example. Estimation of fundamental matrix using RANSAC algorithm from wiki

int point_count = 100;
CvMat* points1;
CvMat* points2;
CvMat* status;
CvMat* fundamental_matrix;

points1 = cvCreateMat(1,point_count,CV_32FC2);
points2 = cvCreateMat(1,point_count,CV_32FC2);
status = cvCreateMat(1,point_count,CV_8UC1);

/* Fill the points here … */
for( i = 0; i < point_count; i++ )
{
points1->data.db[i*2] = ;
points1->data.db[i*2+1] = ;
points2->data.db[i*2] = ;
points2->data.db[i*2+1] = ;
}

fundamental_matrix = cvCreateMat(3,3,CV_32FC1);
int fm_count = cvFindFundamentalMat(
points1,points2,fundamental_matrix,
CV_FM_RANSAC,1.0,0.99,status );

My example code for Fundamental Matrix (source)

with help of code from Paul Smith (UCF vision Lab website) calculating the fundamental matrix using 8-point algorithm.


// first_console_openCV.cpp : Defines the entry point for the console application.
//
#include “stdafx.h”
#include
#include
#include
struct mousedata
{
int cntr ;
CvPoint p1[8];
CvPoint p2[8];

} pp ={0,{},{}};
IplImage* image ;
IplImage* image2 ;

void on_mouse(int event, int x, int y, int flags, void* param)
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN:
{

int cntr = pp.cntr;
char cntr_s[5];

CvFont font;
cvInitFont(&font,CV_FONT_HERSHEY_PLAIN|CV_FONT_ITALIC,1,1,0,1);

CvPoint ptr = cvPoint(x,y);
printf(“(%d,%d)”,ptr.x,ptr.y);
if (cntr <8)
{
itoa(cntr,cntr_s,10);
pp.p1[cntr] = ptr;
cvCircle(image,pp.p1[cntr],1,cvScalar(0,0,255),3);

cvPutText(image,cntr_s,pp.p1[cntr],&font,cvScalar(0,0,255));
cvShowImage(“mywindow”, image);
cvSaveImage(“c:\img1.jpg”,image);

}
else if (cntr <16)
{ pp.p2[cntr-8] = ptr;
cvCircle(image2,pp.p2[cntr-8],1,cvScalar(0,0,255),3);
_itoa(cntr-8,cntr_s,10);
cvPutText(image2,cntr_s,pp.p2[cntr-8],&font,cvScalar(0,0,255));
cvShowImage(“mywindow2”, image2);
cvSaveImage(“c:\img2.jpg”,image2);
}

pp.cntr = cntr + 1;
}
break;

}
}
int _tmain(int argc, _TCHAR* argv[])
{

// mousedada *pp;
pp.cntr = 0;

// load 8-bit, 1 channel grayscale PGM image
image = cvLoadImage(“C:\Documents and Settings\Ramin\Desktop\images\apt1.jpg”);
image2 = cvLoadImage(“C:\Documents and Settings\Ramin\Desktop\images\apt2.jpg”);

// Create a window in which the captured images will be presented
cvNamedWindow(“mywindow”, CV_WINDOW_AUTOSIZE);

// set the mouse call back
cvSetMouseCallback(“mywindow”,on_mouse,0);

// display results
cvShowImage(“mywindow”, image);

// Create a window in which the captured images will be presented
cvNamedWindow(“mywindow2”, CV_WINDOW_AUTOSIZE);

// set the mouse call back
cvSetMouseCallback(“mywindow2”,on_mouse,0 );

cvShowImage(“mywindow2”, image2);

// wait for a keypress
cvWaitKey(0);

//transfer the vector of points to the appropriate opencv matrix structures
int i1,i2;
i2 =0;
int numPoints =8;
CvMat* points1;
CvMat* points2;
CvMat* status;
CvMat* fundMatr;
points1 = cvCreateMat(2,numPoints,CV_32F);
points2 = cvCreateMat(2,numPoints,CV_32F);
status = cvCreateMat(1,numPoints,CV_32F);

for ( i1 = 0; i1 < numPoints; i1++) {

cvSetReal2D(points1,0,i1,pp.p1[i1].x/1);
cvSetReal2D(points1,1,i1,pp.p1[i1].y/1);

cvSetReal2D(points2,0,i1,pp.p2[i1].x/1);
cvSetReal2D(points2,1,i1,pp.p2[i1].y/1);
}

//create the output fundamental matrix
fundMatr = cvCreateMat(3,3,CV_32F);

//see opencv manual for other options in computing the fundamental matrix
int num = cvFindFundamentalMat(points1,points2,fundMatr,CV_FM_8POINT,1.0,0.9999,status);

if( num == 1 )
{
printf(“Fundamental matrix was foundn”);

}
else
{
printf(“Fundamental matrix was not foundn”);
return -1;

}

//now visualize the fundamental matrix
int numOutputPoints;

CvMat* corrLines;
corrLines= cvCreateMat(3,numPoints,CV_32F);

//specify which direction to compute epipolar lines
int startImage = 2;
cvComputeCorrespondEpilines( points2,
startImage,//means points are in image 1
fundMatr,
corrLines);

CvMat* a = cvCreateMat(3,1,CV_32F);
CvMat* b = cvCreateMat(3,1,CV_32F);
CvMat* c = cvCreateMat(3,1,CV_32F);
CvMat* d = cvCreateMat(3,1,CV_32F);

//create output window
char windowName[100];
strcpy_s(windowName,”Output Window”);
cvNamedWindow(windowName,CV_WINDOW_AUTOSIZE);

//for all the points set the point and corresponding epipolar line
//and determine where the epipolar line intersects the image plane
//then display all this info
CvMat* epiLine = cvCreateMat(1,3,CV_32F);
for ( i1 = 0; i1 < numPoints; i1++) {

for (i2 = 0; i2 < 3; i2++) {
cvmSet(epiLine,0,i2,cvmGet(corrLines,i2,i1));
}

CvPoint epipolarLinePoint1, epipolarLinePoint2;

int i4;

CvMat* a = cvCreateMat(3,1,CV_32F);
CvMat* b = cvCreateMat(3,1,CV_32F);
CvMat* c = cvCreateMat(3,1,CV_32F);
CvMat* d = cvCreateMat(3,1,CV_32F);

for ( i4 = 0; i4 < 3; i4++) {

cvSetReal2D(a,i4,0,cvGetReal2D(epiLine,0,i4)/cvGetReal2D(epiLine,0,2));
}

if (abs(cvGetReal2D(epiLine,0,0)) > abs(cvGetReal2D(epiLine,0,1)) ){

double ylim = image->height;

cvSetReal2D(b,0,0,0);
cvSetReal2D(b,1,0,1);
cvSetReal2D(b,2,0,0);

cvCrossProduct(a,b,c);
for ( i4 = 0; i4 < 3; i4++) {
cvSetReal2D(c,i4,0,cvGetReal2D(c,i4,0)/cvGetReal2D(c,2,0));
}

cvSetReal2D(b,0,0,0);
cvSetReal2D(b,1,0,-1.0/ylim);
cvSetReal2D(b,2,0,1);
cvCrossProduct(a,b,d);
for ( i4 = 0; i4 < 3; i4++) {
cvSetReal2D(d,i4,0,cvGetReal2D(d,i4,0)/cvGetReal2D(d,2,0));
}

}
else {
double xlim = image->width;
cvSetReal2D(b,0,0,1);
cvSetReal2D(b,1,0,0);
cvSetReal2D(b,2,0,0);

cvCrossProduct(a,b,c);
for ( i4 = 0; i4 < 3; i4++) {
cvSetReal2D(c,i4,0,cvGetReal2D(c,i4,0)/cvGetReal2D(c,2,0));
}

cvSetReal2D(b,0,0,-1.0/xlim);
cvSetReal2D(b,1,0,0);
cvSetReal2D(b,2,0,1);
cvCrossProduct(a,b,d);
for ( i4 = 0; i4 < 3; i4++) {
cvSetReal2D(d,i4,0,cvGetReal2D(d,i4,0)/cvGetReal2D(d,2,0));
}

}

epipolarLinePoint1.x = cvmGet(c,0,0);
epipolarLinePoint1.y = cvmGet(c,1,0);

epipolarLinePoint2.x = cvmGet(d,0,0);
epipolarLinePoint2.y = cvmGet(d,1,0);

//cvCircle(image2,cvPoint(cvmGet(points2,0,i1),cvmGet(points2,1,i1)),5,CV_RGB(255,255,0),1);

cvShowImage(windowName,image2);
//cvWaitKey(0);

cvLine(image,epipolarLinePoint1,epipolarLinePoint2,CV_RGB(0,255,0));

cvShowImage(windowName,image);
// cvWaitKey(0);
}
cvWaitKey(0);
cvSaveImage(“c:\epipolars.jpg”,image);
return 0;

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: