[View]  [Edit]  [Lock]  [References]  [Attachments]  [History]  [Home]  [Changes]  [Search]  [Help] 

cvWarpPerspectiveQMatrix

This the code I have written to create a single image from to images, its not very perfect but will give you a idea of how to use cvWarpPerspective
Any questions jrmart@alunos.deec.uc.pt


#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>/&#12539;
#include <math.h>

#define _GNU_SOURCE
#define NUMPOINTS  4
#define POINT_DISTANCE 400


CvMat* CamMat = NULL;
CvMat* DistCoef = NULL;
IplImage* src_neg = NULL;
IplImage* src_pos = NULL;
IplImage* dst_neg = NULL;
IplImage* dst_pos = NULL;

IplImage* temp_neg = NULL;
IplImage* temp_pos = NULL;

IplImage* dst = NULL;

IplImage* UMapX_neg = NULL;
IplImage* UMapY_neg = NULL;

IplImage* UMapX_pos = NULL;
IplImage* UMapY_pos = NULL;

CvMat* ImagePoints = NULL;
CvMat* ImagePoints_neg = NULL;
CvMat* ImagePoints_pos = NULL;
CvMat* H_img_neg = NULL;
CvMat* H_img_pos = NULL;

int PointCount = 0;


// Loads the cameras paramenters resultin from the camera calibration toolbox for matlab
void load_cam_param(CvMat* CamMat, CvMat* DistCoef)
{
  FILE* CamFile=fopen("./camera.txt", "r");
  char* line = NULL;
  char focal[]="fc = [ ";
  char principal[]="cc = [ ";
  char distortion[]="kc = [ ";
  int F_DONE=0, P_DONE=0, D_DONE=0;
  float fx=0, fy=0;
  float px=0, py=0;
  float d1=0, d2=0, d3=0, d4=0;
  ssize_t size=0;
  
  while( getline(&line, &size, CamFile) >= 0) //fscanf(CamFile, "%s\n", line) != EOF)
  {
    if( strstr(line, focal) )
    {
      sscanf(line, "fc = [ %f ; %f ];", &fx, &fy);
      F_DONE = 1;
    }
    if( strstr(line, principal) )
    {
      sscanf(line, "cc = [ %f ; %f ];", &px, &py);
      P_DONE = 1;
    }
    if( strstr(line, distortion) )
    {
      sscanf(line, "kc = [ %f ; %f ; %f ; %f];", &d1, &d2, &d3, &d4);
      D_DONE = 1;
    }
    
    if(F_DONE == 1 && P_DONE == 1 && D_DONE == 1)
      break;
  }
  
  cvZero(CamMat);
  cvZero(DistCoef);
  
  CamMat->data.fl[0]=fx;
  CamMat->data.fl[2]=px;
  CamMat->data.fl[4]=fy;
  CamMat->data.fl[5]=py;
  CamMat->data.fl[8]=1;
  
  DistCoef->data.fl[0]=d1;
  DistCoef->data.fl[1]=d2;
  DistCoef->data.fl[2]=d3;
  DistCoef->data.fl[3]=d4;
  
  fclose(CamFile);
  
//   printf("%f 0 0 %f\n", CamMat->data.fl[0], CamMat->data.fl[2]);
//   printf("0 %f 0 %f\n", CamMat->data.fl[4], CamMat->data.fl[5]);
//   printf("0 0 0 1\n\n");
  //   
//   printf("%f %f %f %f\n", DistCoef->data.fl[0], DistCoef->data.fl[1], DistCoef->data.fl[2], DistCoef->data.fl[3]);
}

void rvMouseHomography(int event, int x, int y, int flags, void* a){
  
  if (( event == CV_EVENT_LBUTTONDOWN) && ( PointCount < NUMPOINTS)){
    printf( "\nX= %d\nY= %d\n",x,y);
    ImagePoints->data.fl[ PointCount*2] = x;
    ImagePoints->data.fl[ PointCount*2+1] = y;
	
    PointCount++;
    if ( PointCount == NUMPOINTS)
      printf("Pressione uma tecla\n");
  }
}

//calcs the homography matrix between two planes given 4 points

void rvCalcHomography( char* WindowName, CvMat* Points, CvMat* HomographyMatrix, float MMperPixel)
{
  CvMat* ImgPoints = cvCreateMat(Points->rows, Points->cols, CV_32FC1);
  int* PointCount = NULL;
  PointCount = 0;
  
  cvSetMouseCallback( WindowName, rvMouseHomography, NULL);
  
  printf("Carregue nos pontos\n");
  fflush(stdin);
  
  cvWaitKey(0);
  
  if( Points->data.fl[0] == Points->data.fl[2])
    MMperPixel = fabs( (Points->data.fl[1] - Points->data.fl[3]) / (ImgPoints->data.fl[1] - ImgPoints->data.fl[3]));
  else
    if( Points->data.fl[1] == Points->data.fl[3])
      MMperPixel = fabs( (Points->data.fl[0] - Points->data.fl[2]) / (ImgPoints->data.fl[0] - ImgPoints->data.fl[2]));
  
  cvFindHomography(ImgPoints, Points, HomographyMatrix);
  
  printf("Matriz de Homografia\n");
  
  int i=0;
  for (i=0;i<3;i++)
    printf("%f %f %f \n",HomographyMatrix->data.fl[i*3],HomographyMatrix->data.fl[i*3+1],HomographyMatrix->data.fl[i*3+2]);
  
  cvReleaseMat( &ImgPoints);
  cvReleaseMat( &Points);
}

int main()
{
  src_neg=cvCreateImage( cvSize(800,600), IPL_DEPTH_8U, 3);
  src_pos=cvCreateImage( cvSize(800,600), IPL_DEPTH_8U, 3);
  
  CvRect roi;
  
  IplImage* a = cvLoadImage("./frame_x_neg_00.jpg",1);
  IplImage* b = cvLoadImage("./frame_x_pos_00.jpg",1);
  
  dst_neg=cvCreateImage(cvSize(800,600), IPL_DEPTH_8U, 3);
  dst_pos=cvCreateImage(cvSize(800,600), IPL_DEPTH_8U, 3);
  
  temp_neg=cvCreateImage(cvSize(1100, 900), IPL_DEPTH_8U, 3);
  temp_pos=cvCreateImage(cvSize(1100, 900), IPL_DEPTH_8U, 3);
  
  dst=cvCreateImage(cvSize(1100, 900), IPL_DEPTH_8U, 3);
  
  UMapX_neg=cvCreateImage( cvSize(800,600), IPL_DEPTH_32F, 1);
  UMapY_neg=cvCreateImage( cvSize(800,600), IPL_DEPTH_32F, 1);
  
  UMapX_pos=cvCreateImage( cvSize(800,600), IPL_DEPTH_32F, 1);
  UMapY_pos=cvCreateImage( cvSize(800,600), IPL_DEPTH_32F, 1);
  
  ImagePoints = cvCreateMat( 4, 2, CV_32FC1);
  ImagePoints_neg = cvCreateMat( 4, 2, CV_32FC1);
  ImagePoints_pos = cvCreateMat( 4, 2, CV_32FC1);
  H_img_neg = cvCreateMat( 3, 3, CV_32FC1);
  H_img_pos = cvCreateMat( 3, 3, CV_32FC1);
  
  CamMat = cvCreateMat(3, 3, CV_32FC1);
  DistCoef = cvCreateMat(1, 4, CV_32FC1);
  
  float mmpp_n, mmpp_p;
  
  ImagePoints_neg->data.fl[0]=550;
  ImagePoints_neg->data.fl[1]=50;
  ImagePoints_neg->data.fl[2]=550;
  ImagePoints_neg->data.fl[3]=800;
  ImagePoints_neg->data.fl[4]=50;
  ImagePoints_neg->data.fl[5]=800;
  ImagePoints_neg->data.fl[6]=50;
  ImagePoints_neg->data.fl[7]=50;
  
  ImagePoints_pos->data.fl[0]=1050;
  ImagePoints_pos->data.fl[1]=50;
  ImagePoints_pos->data.fl[2]=1050;
  ImagePoints_pos->data.fl[3]=800;
  ImagePoints_pos->data.fl[4]=550;
  ImagePoints_pos->data.fl[5]=800;
  ImagePoints_pos->data.fl[6]=550;
  ImagePoints_pos->data.fl[7]=50;
  
  cvNamedWindow("img_neg",1);
  cvNamedWindow("img_pos",1);
  
//   cvShowImage("img_neg", a);
//   cvShowImage("img_pos", b);
  
//   cvWaitKey(0);
  
  printf("w: %d h: %d", cvGetSize(b).width, cvGetSize(b).height);
  
  roi.x=50;
  roi.y=50;
  roi.width=640;
  roi.height=480;
  
  cvSetImageROI(src_neg, roi);
  
  cvCopy(a, src_neg, 0);
  
  cvResetImageROI(src_neg);
  
  cvSetImageROI(src_pos, roi);

  cvCopy(b, src_pos, 0);
  
  cvResetImageROI(src_pos);
  
  load_cam_param(CamMat, DistCoef);
  
  cvInitUndistortMap( CamMat, DistCoef, UMapX_neg, UMapY_neg);
  
  cvRemap(src_neg, dst_neg, UMapX_neg, UMapY_neg, CV_INTER_LINEAR, cvScalarAll(0));
  
  cvInitUndistortMap( CamMat, DistCoef, UMapX_pos, UMapY_pos);
  
  cvRemap(src_pos, dst_pos, UMapX_pos, UMapY_pos, CV_INTER_LINEAR, cvScalarAll(0));
  
  cvShowImage("img_neg", dst_neg);
  cvShowImage("img_pos", dst_pos);
  
  cvWaitKey(0);
  
  rvCalcHomography("img_neg", ImagePoints_neg, H_img_neg, mmpp_n);
  
  rvCalcHomography("img_pos",  ImagePoints_pos, H_img_pos, mmpp_n);
  
  cvWarpPerspective(dst_neg, temp_neg, H_img_neg, CV_WARP_FILL_OUTLIERS,  cvScalarAll(0));
  
  cvWarpPerspective(dst_pos, temp_pos, H_img_pos, CV_WARP_FILL_OUTLIERS,  cvScalarAll(0));
  
//   cvShowImage("img_neg", temp_neg);
//   cvShowImage("img_pos", temp_pos);
  
//   cvWaitKey(0);
  roi.x=0;
  roi.y=30;
  roi.width=550;
  roi.height=900;
  
  cvSetImageROI(temp_neg, roi);
  cvSetImageROI(dst, roi);
  
  cvCopy(temp_neg, dst, NULL);
  
  cvResetImageROI(dst);
  
  roi.x=550;
  roi.y=30;
  roi.width=550;
  roi.height=900;
  
  cvSetImageROI(temp_pos, roi);
  cvSetImageROI(dst, roi);
  
  cvCopy(temp_pos, dst, NULL);
  
  cvNamedWindow("final", 1);
  cvResetImageROI(dst);
  cvShowImage("final", dst);
  
  cvWaitKey(0);
  
//   cvSaveImage("img_undis_neg.bmp", dst_neg);
//   cvSaveImage("img_undis_pos.bmp", dst_pos);
  
//   cvSaveImage("img_dis_neg.bmp", src_neg);
//   cvSaveImage("img_dis_pos.bmp", src_pos);
  
//   cvSaveImage("img_final_neg.bmp", dst);
  
  return 0;
}


Uploaded Image: img dis neg.png
Original Image 1
Uploaded Image: img dis pos.png
Original Image 2
Uploaded Image: img final.png
Final Image the two upper images rotated and moved
Uploaded Image: img dis neg.png