Showing posts with label surf. Show all posts
Showing posts with label surf. Show all posts

6/02/2015

opencv 3.0 rc1, example source code for surf and matching (gpu version)

This code is SURF and Matching test in opencv 3.0 rc1.

Especially, for using surf class, we have to add extra library when build opencv 3.0 rc1.
The extra lib is opened in github named opencv_contrib.

refer to this page.
http://study.marearts.com/2015/01/mil-boosting-tracker-test-in-opencv-30.html

surf(gpu version) is included in xfeatures2d/cuda.hpp
and cpu version is xfeatures2d/nonfree.hpp

As we know, surf, sift are still nonfree. very not good!..-.-

necessary dlls

result


Now, refer this example code.
This cod is converted from http://study.marearts.com/2014/07/opencv-study-surf-gpu-and-matching.html.


#include < stdio.h>  
#include < iostream>  


#include < opencv2\opencv.hpp>  
#include < opencv2\core.hpp>
#include < opencv2\highgui.hpp> 
#include < opencv2\cudaarithm.hpp>
#include < opencv2\xfeatures2d\cuda.hpp>
#include < opencv2\cudafeatures2d.hpp>
//#include < opencv2\xfeatures2d\nonfree.hpp>



#ifdef _DEBUG          
#pragma comment(lib, "opencv_core300d.lib")
#pragma comment(lib, "opencv_highgui300d.lib")  
#pragma comment(lib, "opencv_imgcodecs300d.lib")
#pragma comment(lib, "opencv_cudafeatures2d300d.lib")
#pragma comment(lib, "opencv_xfeatures2d300d.lib")
#pragma comment(lib, "opencv_features2d300d.lib")
#else  
#pragma comment(lib, "opencv_core300.lib")
#pragma comment(lib, "opencv_highgui300.lib")
#pragma comment(lib, "opencv_imgcodecs300.lib")
#pragma comment(lib, "opencv_cudafeatures2d300.lib")
#pragma comment(lib, "opencv_xfeatures2d300.lib")
#pragma comment(lib, "opencv_features2d300.lib")
#endif   


using namespace cv;
using namespace std;

void main()
{


 
 cuda::GpuMat img1(imread("M:\\____videoSample____\\Image\\A2.jpg", CV_LOAD_IMAGE_GRAYSCALE));
 cuda::GpuMat img2(imread("M:\\____videoSample____\\Image\\A3.jpg", CV_LOAD_IMAGE_GRAYSCALE));

 
 /////////////////////////////////////////////////////////////////////////////////////////  
 unsigned long t_AAtime = 0, t_BBtime = 0;
 float t_pt;
 float t_fpt;
 t_AAtime = getTickCount();
 /////////////////////////////////////////////////////////////////////////////////////////  

 
 cuda::SURF_CUDA surf(400); 
 // detecting keypoints & computing descriptors   
 cuda::GpuMat keypoints1GPU, keypoints2GPU;
 cuda::GpuMat descriptors1GPU, descriptors2GPU;
 surf(img1, cuda::GpuMat(), keypoints1GPU, descriptors1GPU);
 surf(img2, cuda::GpuMat(), keypoints2GPU, descriptors2GPU);

 cout << "FOUND " << keypoints1GPU.cols << " keypoints on first image" << endl;
 cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl;

 // matching descriptors   
 vector< vector< DMatch> > matches;
 Ptr< cuda::DescriptorMatcher > matcher = cuda::DescriptorMatcher::createBFMatcher();
 matcher->knnMatch(descriptors1GPU, descriptors2GPU, matches, 2);

 // downloading results  Gpu -> Cpu  
 vector< KeyPoint> keypoints1, keypoints2;
 vector< float> descriptors1, descriptors2;
 surf.downloadKeypoints(keypoints1GPU, keypoints1);
 surf.downloadKeypoints(keypoints2GPU, keypoints2);
 //surf.downloadDescriptors(descriptors1GPU, descriptors1);   
 //surf.downloadDescriptors(descriptors2GPU, descriptors2);  

 vector< KeyPoint> matchingKey1, matchingKey2;
 std::vector< DMatch > good_matches;
 for (int k = 0; k < min(descriptors1GPU.rows - 1, (int)matches.size()); k++)
 {
  if ((matches[k][0].distance < 0.6*(matches[k][1].distance)) && ((int)matches[k].size() <= 2 && (int)matches[k].size()>0))
  {
   good_matches.push_back(matches[k][0]);

  }
 }

 t_BBtime = getTickCount();
 t_pt = (t_BBtime - t_AAtime) / getTickFrequency();
 t_fpt = 1 / t_pt;
 printf("feature extraction = %.4lf / %.4lf \n", t_pt, t_fpt);

 // drawing the results   
 Mat img_matches;
 Mat img11, img22;
 img1.download(img11);
 img2.download(img22);

 //drawMatches(img11, matchingKey1, img22, matchingKey2, good_matches, img_matches);   
 drawMatches(img11, keypoints1, img22, keypoints2, good_matches, img_matches);

 namedWindow("matches", 0);
 imshow("matches", img_matches);
 waitKey(0);
 
 matcher.release();

}


7/27/2014

(OpenCV Study) Surf GPU and Matching (SURF_GPU, BruteForceMatcher_GPU example source code)

This is example source code of Matching using surf and bruteForceMathing of gpu version.
I think this simple example source code is useful to your gpu mode feature matching project.

This is source image.
The RC car is my favorite machine.


 
 
The figure is result of surf matching.



Processing time is 0.4028second and 2.4828 fps.
Image size is 1920x1080.


#include < stdio.h>
#include < iostream>

#include < opencv2\opencv.hpp>
#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
#include < opencv2\gpu\gpu.hpp>
#include < opencv2\stitching\detail\matchers.hpp >  


#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")
#pragma comment(lib, "opencv_gpu247d.lib")
#pragma comment(lib, "opencv_features2d247d.lib")
#pragma comment(lib, "opencv_highgui247d.lib")
#pragma comment(lib, "opencv_nonfree247d.lib")
#else
#pragma comment(lib, "opencv_core247.lib")
#pragma comment(lib, "opencv_gpu247.lib")
#pragma comment(lib, "opencv_features2d247.lib")
#pragma comment(lib, "opencv_highgui247.lib")
#pragma comment(lib, "opencv_nonfree247.lib")
#endif 


using namespace cv;
using namespace std;

void main()
{
gpu::GpuMat img1(imread("C:\\videoSample\\Image\\Picture6.jpg", CV_LOAD_IMAGE_GRAYSCALE)); 
    gpu::GpuMat img2(imread("C:\\videoSample\\Image\\Picture7.jpg", CV_LOAD_IMAGE_GRAYSCALE)); 

 
 /////////////////////////////////////////////////////////////////////////////////////////
 unsigned long t_AAtime=0, t_BBtime=0;
 float t_pt;
 float t_fpt;
 t_AAtime = getTickCount(); 
 /////////////////////////////////////////////////////////////////////////////////////////

    gpu::SURF_GPU surf(400);
    // detecting keypoints & computing descriptors 
    gpu::GpuMat keypoints1GPU, keypoints2GPU; 
    gpu::GpuMat descriptors1GPU, descriptors2GPU; 
    surf(img1, gpu::GpuMat(), keypoints1GPU, descriptors1GPU); 
    surf(img2, gpu::GpuMat(), keypoints2GPU, descriptors2GPU); 
    
    cout << "FOUND " << keypoints1GPU.cols << " keypoints on first image" << endl; 
    cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl; 

    // matching descriptors 
    gpu::BruteForceMatcher_GPU< L2< float> > matcher;    
 vector< vector< DMatch> > matches; 
 matcher.knnMatch(descriptors1GPU, descriptors2GPU, matches, 2); 
    
    // downloading results  Gpu -> Cpu
    vector< KeyPoint> keypoints1, keypoints2; 
    vector< float> descriptors1, descriptors2; 
    surf.downloadKeypoints(keypoints1GPU, keypoints1);
    surf.downloadKeypoints(keypoints2GPU, keypoints2);
    //surf.downloadDescriptors(descriptors1GPU, descriptors1); 
    //surf.downloadDescriptors(descriptors2GPU, descriptors2);

 vector< KeyPoint> matchingKey1, matchingKey2;
 std::vector< DMatch > good_matches;
 for(int k = 0; k < min(descriptors1GPU.rows-1,(int) matches.size()); k++) 
    {
        if((matches[k][0].distance < 0.6*(matches[k][1].distance)) && ((int) matches[k].size()<=2 && (int) matches[k].size()>0))
        {
            good_matches.push_back(matches[k][0]);

        }
    }
 


 
 t_BBtime = getTickCount();
 t_pt = (t_BBtime - t_AAtime)/getTickFrequency();
 t_fpt = 1/t_pt;
 printf("feature extraction = %.4lf / %.4lf \n",  t_pt, t_fpt );



 
 
 
    // drawing the results 
    Mat img_matches; 
 Mat img11, img22;
 img1.download(img11);
 img2.download(img22);
 
 //drawMatches(img11, matchingKey1, img22, matchingKey2, good_matches, img_matches); 
    drawMatches(img11, keypoints1, img22, keypoints2, good_matches, img_matches); 

 //drawKeypoints(img11, keypoints1, img_matches);
 

    namedWindow("matches", 0); 
    imshow("matches", img_matches); 
    waitKey(0); 
}




refer to this posting
optical flow and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-opticalflow-gpu-feature.html
orb feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-orb-gpu-feature-extraction.html
surf feature and matching using gpu
http://feelmare.blogspot.kr/2014/07/opencv-study-surf-gpu-and-matching.html

12/17/2013

Finding largest subset images that is only adjacent(subsequnce) images, (OpenCV, SurfFeaturesFinder, BestOf2NearestMatcher, leaveBiggestComponent funcions example souce code)

The souce code flow is like that...

1.
find features in each images using SurfFeaturesFinder function.
Features value is contained in the ImageFeatures structure.

2.
Matching features.
Matcher(features, pairwise_matches, matching_mask)
in the source code, features is vector.
So the Matcher function get matcing value of each pair images.

3.
leave biggest component,
Using conf_threshold, the function leaves largest correlation images.

Input
Input image is 6 images.
4 images are sequence images, 2 images is another sequence images.

Output
The souce code gives the result that is index of subset images of 4 images component.



////
#include < stdio.h >  
#include < opencv2\opencv.hpp >  
#include < opencv2\features2d\features2d.hpp >
#include < opencv2\nonfree\features2d.hpp >
#include < opencv2\stitching\detail\matchers.hpp >
#include < opencv2\stitching\stitcher.hpp >


#ifdef _DEBUG  
#pragma comment(lib, "opencv_core247d.lib")   
//#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing  
//#pragma comment(lib, "opencv_objdetect247d.lib")   
//#pragma comment(lib, "opencv_gpu247d.lib")  
#pragma comment(lib, "opencv_features2d247d.lib")  
#pragma comment(lib, "opencv_highgui247d.lib")  
//#pragma comment(lib, "opencv_ml247d.lib")
#pragma comment(lib, "opencv_stitching247d.lib");
#pragma comment(lib, "opencv_nonfree247d.lib");

#else  
#pragma comment(lib, "opencv_core247.lib")  
//#pragma comment(lib, "opencv_imgproc247.lib")  
//#pragma comment(lib, "opencv_objdetect247.lib")  
//#pragma comment(lib, "opencv_gpu247.lib")  
#pragma comment(lib, "opencv_features2d247.lib")  
#pragma comment(lib, "opencv_highgui247.lib")  
//#pragma comment(lib, "opencv_ml247.lib")  
#pragma comment(lib, "opencv_stitching247.lib");
#pragma comment(lib, "opencv_nonfree247.lib");
#endif  

using namespace cv;  
using namespace std;


void main()  
{
 vector< Mat > vImg;
 Mat rImg;

 vImg.push_back( imread("./m7.jpg") );
 vImg.push_back( imread("./B1.jpg") );
 vImg.push_back( imread("./m9.jpg") );
 vImg.push_back( imread("./m6.jpg") );
 vImg.push_back( imread("./B2.jpg") );
 vImg.push_back( imread("./m8.jpg") );
 

 //feature extract
 detail::SurfFeaturesFinder FeatureFinder;
 vector< detail::ImageFeatures> features;
 
 for(int i=0; i< vImg.size(); ++i)
 {  
  detail::ImageFeatures F;
  FeatureFinder(vImg[i], F);  
  features.push_back(F);
  features[i].img_idx = i;
  printf("Keypoint of [%d] - %d points \n", i, features[i].keypoints.size() );
 }
 FeatureFinder.collectGarbage();

 //match
 vector<  int> indices_;
 double conf_thresh_ = 1.0;
 Mat matching_mask;
 vector<  detail::MatchesInfo> pairwise_matches;
 detail::BestOf2NearestMatcher Matcher;
 Matcher(features, pairwise_matches, matching_mask);
 Matcher.collectGarbage();

 printf("\nBiggest subset is ...\n");
 // Leave only images we are sure are from the same panorama 
 indices_ = detail::leaveBiggestComponent(features, pairwise_matches, (float)conf_thresh_);
 Matcher.collectGarbage();

 for (size_t i = 0; i <  indices_.size(); ++i)
    {
  printf("%d \n", indices_[i] );
 }
 

}

////









12/13/2013

How to use mask parameter for SURF feature detector (OpenCV)

The function of mask parameter is we can extract features only desired position(Rect).

This is mask.
 
This is output.
 
We can see features is extracted only white rect.
This is example source code.
 
 
 
 

/////
#include < stdio.h >  
#include < opencv2\opencv.hpp >
#include < opencv2\features2d\features2d.hpp >
#include < opencv2\nonfree\features2d.hpp >

#ifdef _DEBUG  
#pragma comment(lib, "opencv_core246d.lib")   
//#pragma comment(lib, "opencv_imgproc246d.lib")   //MAT processing  
//#pragma comment(lib, "opencv_objdetect246d.lib")   
//#pragma comment(lib, "opencv_gpu246d.lib")  
#pragma comment(lib, "opencv_features2d246d.lib")  
#pragma comment(lib, "opencv_highgui246d.lib")  
//#pragma comment(lib, "opencv_ml246d.lib")
//#pragma comment(lib, "opencv_stitching246d.lib");
#pragma comment(lib, "opencv_nonfree246d.lib");

#else  
#pragma comment(lib, "opencv_core246.lib")  
//#pragma comment(lib, "opencv_imgproc246.lib")  
//#pragma comment(lib, "opencv_objdetect246.lib")  
//#pragma comment(lib, "opencv_gpu246.lib")  
#pragma comment(lib, "opencv_features2d246.lib")  
#pragma comment(lib, "opencv_highgui246.lib")  
//#pragma comment(lib, "opencv_ml246.lib")  
//#pragma comment(lib, "opencv_stitching246.lib");
#pragma comment(lib, "opencv_nonfree246.lib");
#endif  

using namespace cv;  
using namespace std;


void main()  
{
 
 //SURF_GPU example source code
 Mat inImg,outImg;
 vector< cv::KeyPoint > src_keypoints;
 vector< float > src_descriptors;
 
 //image load
 inImg = imread("ship.png",0);

 //FeatureFinder 
 SurfFeatureDetector FeatureFinder(400);

 //make mask
 Mat mask = Mat::zeros(inImg.size(), CV_8U);  
 Mat roi(mask, Rect(400,400,400,400) );
 roi = Scalar(255, 255, 255);  

 /*
 //The mode to set multiple masks
 vector< Rect > mask_rect;
 mask_rect.push_back(Rect(0,0,200,200) );
 mask_rect.push_back(Rect(200,200,200,200) );
 mask_rect.push_back(Rect(400,400,200,200) );
 mask_rect.push_back(Rect(600,600,200,200) );

 Mat mask = Mat::zeros(inImg.size(), CV_8U);  
 for(int i=0; i< mask_rect.size(); ++i)
 {
  Mat roi(mask, mask_rect[i] ); 
  roi = Scalar(255, 255, 255);  
 }
 */

 //Feature Extraction
 FeatureFinder.detect( inImg, src_keypoints , mask);

 //Features Draw
 drawKeypoints( inImg, src_keypoints, outImg, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );

 imshow("Show", outImg); 
 imshow("mask", mask); 
 imshow("roi", roi); 
 waitKey(0);

 //save to file
 imwrite("output.jpg", outImg);
 imwrite("mask.jpg", mask);
 imwrite("roi.jpg", roi);

}

/////


If you want to set one more masks, see the comment section.
This source code is advance on this page(http://feelmare.blogspot.kr/2013/12/surffeaturedetector-exmaple-source-code.html).

SurfFeatureDetector exmaple source code (OpenCV)

This is 'SurfFeatureDetector' example source code.
On this page(http://feelmare.blogspot.kr/2013/12/surfgpu-example-source-code-feature.html), I introduced SURF_GPU.
In my case, The processing time difference is small.
GPU-> 0.99 sec, CPU-> 1.04 sec.


 



 

////
#include < stdio.h >  
#include < opencv2\opencv.hpp >
#include < opencv2\features2d\features2d.hpp >
#include < opencv2\nonfree\features2d.hpp >

#ifdef _DEBUG  
#pragma comment(lib, "opencv_core246d.lib")   
//#pragma comment(lib, "opencv_imgproc246d.lib")   //MAT processing  
//#pragma comment(lib, "opencv_objdetect246d.lib")   
//#pragma comment(lib, "opencv_gpu246d.lib")  
#pragma comment(lib, "opencv_features2d246d.lib")  
#pragma comment(lib, "opencv_highgui246d.lib")  
//#pragma comment(lib, "opencv_ml246d.lib")
//#pragma comment(lib, "opencv_stitching246d.lib");
#pragma comment(lib, "opencv_nonfree246d.lib");

#else  
#pragma comment(lib, "opencv_core246.lib")  
//#pragma comment(lib, "opencv_imgproc246.lib")  
//#pragma comment(lib, "opencv_objdetect246.lib")  
//#pragma comment(lib, "opencv_gpu246.lib")  
#pragma comment(lib, "opencv_features2d246.lib")  
#pragma comment(lib, "opencv_highgui246.lib")  
//#pragma comment(lib, "opencv_ml246.lib")  
//#pragma comment(lib, "opencv_stitching246.lib");
#pragma comment(lib, "opencv_nonfree246.lib");
#endif  

using namespace cv;  
using namespace std;


void main()  
{
/////CPU mode


//processign tiem measurement
unsigned long AAtime=0, BBtime=0;

//SURF_GPU example source code
Mat inImg,outImg;
vector src_keypoints;
vector src_descriptors;


//image load
inImg = imread("ship.png",0);

//FeatureFinder 
SurfFeatureDetector FeatureFinder(400);

//processing time measure
AAtime = getTickCount();

//Feature Extraction
FeatureFinder.detect( inImg, src_keypoints );

//Processing time measurement
BBtime = getTickCount(); 

//Features Draw
drawKeypoints( inImg, src_keypoints, outImg, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );

imshow("Show", outImg); 
printf("Processing time = %.2lf(sec) \n",  (BBtime - AAtime)/getTickFrequency() );
printf("Features %d\n", src_keypoints.size() );

waitKey(0);

//save to file
imwrite("output.jpg", outImg);

}
////





SURF_GPU example source code (feature finder using GPU )

This is example source code about SURF_GPU.
The time of processing is taken 0.99 sec on the 1787x1510 image size.
My environment is
Intel(r) core(TM) i5-3570 cpu@3.4ghz 3.80 Ghz
NVIDA Geforce GTX 650






Example source code



//////
#include < stdio.h >  
#include < opencv2\opencv.hpp >  
#include < opencv2\nonfree\gpu.hpp >


#ifdef _DEBUG  
#pragma comment(lib, "opencv_core246d.lib")   
//#pragma comment(lib, "opencv_imgproc246d.lib")   //MAT processing  
//#pragma comment(lib, "opencv_objdetect246d.lib")   
//#pragma comment(lib, "opencv_gpu246d.lib")  
#pragma comment(lib, "opencv_features2d246d.lib")  
#pragma comment(lib, "opencv_highgui246d.lib")  
//#pragma comment(lib, "opencv_ml246d.lib")
//#pragma comment(lib, "opencv_stitching246d.lib");
#pragma comment(lib, "opencv_nonfree246d.lib");

#else  
#pragma comment(lib, "opencv_core246.lib")  
//#pragma comment(lib, "opencv_imgproc246.lib")  
//#pragma comment(lib, "opencv_objdetect246.lib")  
//#pragma comment(lib, "opencv_gpu246.lib")  
#pragma comment(lib, "opencv_features2d246.lib")  
#pragma comment(lib, "opencv_highgui246.lib")  
//#pragma comment(lib, "opencv_ml246.lib")  
//#pragma comment(lib, "opencv_stitching246.lib");
#pragma comment(lib, "opencv_nonfree246.lib");
#endif  

using namespace cv;  
using namespace std;


void main()  
{
 //processign tiem measurement
 unsigned long AAtime=0, BBtime=0;

 //SURF_GPU example source code
 Mat inImg;
 vector src_keypoints;
 vector src_descriptors;

 gpu::GpuMat inImg_g;
 gpu::GpuMat src_keypoints_gpu, src_descriptors_gpu;

 //image load
 inImg = imread("ship.png",0);

 //FeatureFinder 
 gpu::SURF_GPU FeatureFinder_gpu(400);

 //processing time measure
 AAtime = getTickCount();
 inImg_g.upload(inImg);

 //Feature Extraction
 FeatureFinder_gpu(inImg_g, gpu::GpuMat(), src_keypoints_gpu, src_descriptors_gpu, false);

 //Processing time measurement
 BBtime = getTickCount(); 
 
 //descriptor down
 FeatureFinder_gpu.downloadKeypoints(src_keypoints_gpu, src_keypoints); 
 FeatureFinder_gpu.downloadDescriptors(src_descriptors_gpu, src_descriptors);
 
 //Features Draw
 //특징점 뿌리기 1
 drawKeypoints(inImg, src_keypoints, inImg, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );
 
 imshow("Show", inImg); 

 printf("Processing time = %.2lf(sec) \n",  (BBtime - AAtime)/getTickFrequency() );
 printf("Features %d\n", src_keypoints.size() );

 waitKey(0);

 //save to file
 imwrite("output.jpg", inImg);
}

///

10/28/2013

Two view of cam to one screen using stitching algorithm(OpenCV, example source code), (mosaic)

This source code based on ->
http://feelmare.blogspot.kr/2011/08/two-image-mosaic-paranoma-based-on-sift.html
This link page introduces how to make a mosaic image from two adjacent images.
I made two cam video to one stitching video using the source code.

After run, operate the program of 3 keys.
'q' key is quit, 'p' key is processing(stitching), 'r' is reset.








Mat TwoInOneOut(Mat Left, Mat Right);

void main()
{
 VideoCapture stream1(0);   //0 is the id of video device.0 if you have only one camera
 VideoCapture stream2(1);   //0 is the id of video device.0 if you have only one camera
 
 if (!stream1.isOpened()) { //check if video device has been initialised
  cout << "cannot open camera 1";
 }

 if (!stream2.isOpened()) { //check if video device has been initialised
  cout << "cannot open camera 2";
 }


// namedWindow("Processing");
// namedWindow("Left");
// namedWindow("Right");

 Mat H;
 int mode=0;
 //unconditional loop
 while (true) {
  Mat cameraFrame1;
  stream1.read(cameraFrame1); //get one frame form video
  

  Mat cameraFrame2;
  stream2.read(cameraFrame2); //get one frame form video

  if(mode == 0)
  {
   imshow("Left", cameraFrame1);
   imshow("Right", cameraFrame2);
  }

  Mat Left(cameraFrame1.rows, cameraFrame1.cols, CV_8U);
  Mat Right(cameraFrame1.rows, cameraFrame1.cols, CV_8U);
  cvtColor(cameraFrame1, Left, CV_RGB2GRAY, CV_8U);
  cvtColor(cameraFrame2, Right, CV_RGB2GRAY, CV_8U);

  if (waitKey(30) == 'p')
  {
   printf("Homography Matrix Processing\n");
   H = TwoInOneOut(Left, Right);
   mode=1;
   destroyWindow("Left");
   destroyWindow("Right");
  }

  if(waitKey(30) == 'r')
  {
   printf("normal mode\n");
   destroyWindow("Processing");
   mode=0;
  }
  
  //printf("%d %d\n", H.cols, H.rows);
  if(H.cols == 3 && H.rows == 3)
  {
   Mat WarpImg( Left.rows*2, Left.cols*2, cameraFrame1.depth() );
      //printf("%d %d\n", A.depth(), A.channels());
   warpPerspective(cameraFrame2, WarpImg, H, Size(WarpImg.cols, WarpImg.rows));
   Mat tempWarpImg = WarpImg(Rect(0,0,Left.cols,Left.rows));
   cameraFrame1.copyTo(tempWarpImg);

   /*
   Mat WarpImg( Left.rows*2, Left.cols*2, CV_8U);
      //printf("%d %d\n", A.depth(), A.channels());
   warpPerspective(Right, WarpImg, H, Size(WarpImg.cols, WarpImg.rows));
   Mat tempWarpImg = WarpImg(Rect(0,0,Left.cols,Left.rows));
   Left.copyTo(tempWarpImg);
   */
   if(mode ==1)
    imshow("Processing", WarpImg );
  //Mat t = WarpImg( Rect(0,0,B.cols, B.rows));

  }

  //imshow("Processing", t );

  if (waitKey(30) == 'q')
   break;
 }

 destroyAllWindows();
 
 
}


Mat TwoInOneOut(Mat Left, Mat Right)
{
 Mat H;
 

 if(Left.channels() != 1 || Right.channels() != 1)
 {
  printf("Channel Error\n");
  return H;
 }

 /////////////////
 //Detect the keypoints using SURF Detector
    int minHessian = 300; //1500; 
    SurfFeatureDetector detector( minHessian );
 SurfDescriptorExtractor extractor;

 /////////////////
 //A
    std::vector< KeyPoint> kp_Left;
    detector.detect( Left, kp_Left );    
 Mat des_Left;
    extractor.compute( Left, kp_Left, des_Left );

 /////////////////
 //B 
 std::vector< KeyPoint> kp_Right;
 detector.detect( Right, kp_Right );
 Mat des_Right;
 extractor.compute( Right, kp_Right, des_Right );

 /////////////////
 //Match
 std::vector< vector< DMatch > > matches;
 FlannBasedMatcher matcher;
 matcher.knnMatch(des_Left, des_Right, matches, 2);
 //matcher.knnMatch(des_Right, des_Left, matches, 2);
 std::vector< DMatch > good_matches;
 good_matches.reserve(matches.size());  

 for (size_t i = 0; i < matches.size(); ++i)
 { 
  if (matches[i].size() < 2)
   continue;

  const DMatch &m1 = matches[i][0];
  const DMatch &m2 = matches[i][1];

  if(m1.distance <= 0.7 * m2.distance)        
   good_matches.push_back(m1);     
 }

 //Draw only "good" matches
 Mat img_matches;
    drawMatches( Left, kp_Left, Right, kp_Right, good_matches, 
  img_matches, Scalar::all(-1), Scalar::all(-1), 
  vector< char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
 imshow("Match", img_matches);

    /////////////////
 //Find H
 if(good_matches.size() > 20 )
 {
  std::vector< Point2f >  LeftMatchPT;
  std::vector< Point2f >  RightMatchPT;
  
  for( unsigned int i = 0; i < good_matches.size(); i++ )
  {
   //-- Get the keypoints from the good matches
   LeftMatchPT.push_back( kp_Left[ good_matches[i].queryIdx ].pt );
   RightMatchPT.push_back( kp_Right[ good_matches[i].trainIdx ].pt );
  }

  H = findHomography( RightMatchPT, LeftMatchPT, CV_RANSAC );
  //H = findHomography( LeftMatchPT,RightMatchPT, CV_RANSAC );
 }


 return H;


}

////
The source code
-> here