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