void App::process()
{
    if (sources.empty())
    {
        cout << "Loading default images...\n";
        sources.resize(2);
        sources[0] = new ImageSource("data/stitching/t100mA.JPG");
        sources[1] = new ImageSource("data/stitching/t100mB.JPG");
    }

    stitcher_cpu.setFeaturesMatcher(new cv::detail::BestOf2NearestMatcher(false, 0.5));
    stitcher_gpu.setFeaturesMatcher(new cv::detail::BestOf2NearestMatcher(true, 0.5));

    cout << "\nControls:\n"
         << "  space - chanege CPU/GPU mode\n\n";

    vector<Mat> imgs(sources.size());
    Mat pano;

    double total_fps = 0;
    bool first_iter_cpu = true;
    bool first_iter_gpu = true;

    while (!exited)
    {
        int64 start = getTickCount();

        for (size_t i = 0; i < sources.size(); ++i)
            sources[i]->next(imgs[i]);

        int64 proc_start = getTickCount();

        if (use_gpu)
        {
            if (first_iter_gpu)
            {
                stitcher_gpu.estimateTransform(imgs);
                first_iter_gpu = false;
            }
            stitcher_gpu.composePanorama(imgs, pano);
        }
        else
        {
            if (first_iter_cpu)
            {
                stitcher_cpu.estimateTransform(imgs);
                first_iter_cpu = false;
            }
            stitcher_cpu.composePanorama(imgs, pano);
        }

        double proc_fps = getTickFrequency()  / (getTickCount() - proc_start);

        stringstream msg; msg << "total FPS = " << setprecision(4) << total_fps;
        printText(pano, msg.str(), 0);

        msg.str(""); msg << "processing FPS = " << setprecision(4) << proc_fps;
        printText(pano, msg.str(), 1);

        printText(pano, use_gpu ? "mode = GPU" : "mode = CPU", 2);

        imshow("stitching_demo", pano);

        processKey(waitKey(3) & 0xff);

        total_fps = getTickFrequency()  / (getTickCount() - proc_start);

        cout << endl;
    }
}
Exemple #2
0
int main(int argc, char* argv[])
{
    vector<Mat> imgs;

    cout << "reading image" << endl;
    for (int i = 1; i < argc; ++i) {
        Mat img = imread(argv[i]);
        if (!img.empty()) {
            imgs.push_back(img);
        }
    }
    cout << "finishing read" << endl;
    cout << "starting stitch" << endl;

    Mat pano;
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);

    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << int(status) << endl;
        return -1;
    }

    imwrite(result_name, pano);
    namedWindow("test", 0);
    imshow("test", pano);
    waitKey();

    return 0;
}
int stitch()
{
	Mat a,b,c, stitched; 

	//a = imread("asd.jpg"); 
	//b = imread("bsd.jpg"); 
	//c = imread("csd.jpg"); 

	/*
	a = imread("test1.jpg"); 
	b = imread("test2.jpg"); 
	c = imread("test3.jpg"); 

	a = imread("1.jpg"); 
	b = imread("2.jpg"); 
	c = imread("3.jpg"); 

	a = imread("input1.jpg"); 
	b = imread("input2.jpg"); 
	*/
	
	a = imread("scene1.png"); 
	b = imread("scene2.png"); 


	//resize(a, a, Size(0,0), 0.4, 0.4);
	//resize(b, b, Size(0,0), 0.4, 0.4); 
	//resize(c, c, Size(0,0), 0.4, 0.4); 

	vector<Mat> imgs; 
	imgs.push_back(a); 
	//imgs.push_back(c); 
	imgs.push_back(b); 


	imshow("a", a); 
	imshow("b", b); 
	//imshow("c", c); 

	Stitcher stitcher = Stitcher::createDefault(); 
	Stitcher::Status status = stitcher.stitch(imgs, stitched); 
	if(status == Stitcher::OK)
	{
		//resize(stitched, stitched, Size(0,0), 0.3, 0.3); 
		imshow("stitched", stitched); 
	}
	else if(status == Stitcher::ERR_NEED_MORE_IMGS)
	{
		cout << "want more images" << endl; 
	}
	else
	{
		cout << "what?" << endl; 
	}


	waitKey(12345678); 

	return 0; 
}
Exemple #4
0
int main(int argc, char* argv[])
{
//	int retval = parseCmdArgs(argc, argv);
//	if (retval) return -1;

	Mat img1 = imread("DJI_0001.jpg");
	Mat img2 = imread("DJI_0002.jpg");
	if (img1.cols == 0 || img2.cols == 0) {
		cout << "Error reading file "<< endl;
		return -1;
	}
	imgs.push_back(img1);
	imgs.push_back(img2);

	Mat pano;
	Stitcher stitcher = Stitcher::createDefault();
	Stitcher::Status status = stitcher.stitch(imgs, pano);

	if (status != Stitcher::OK)
	{
		cout << "Can't stitch images, error code = " << int(status) << endl;
		return -1;
	}

	namedWindow("result");
	imwrite("pano.jpg", pano);
//	imshow("result", pano);
	return 0;
}
void main()
{
	vector< Mat > vImg;
	Mat rImg;

	auto image_paths = get_all_files_names_within_folder(".");

	for (auto path : image_paths) {
		if (path.find(".jpg") != string::npos) {
			cout << path << endl;
			vImg.push_back(imread(path));
		}
	}

	Stitcher stitcher = Stitcher::createDefault();


	unsigned long AAtime = 0, BBtime = 0; //check processing time  
	AAtime = getTickCount(); //check processing time  

	Stitcher::Status status = stitcher.stitch(vImg, rImg);

	BBtime = getTickCount(); //check processing time   
	printf("%.2lf sec \n", (BBtime - AAtime) / getTickFrequency()); //check processing time  

	if (Stitcher::OK == status) {
		namedWindow("Stitching Result", WINDOW_NORMAL | CV_WINDOW_KEEPRATIO);
		imshow("Stitching Result", rImg);
		waitKey(0);
	}

	else
		cout << "Stitching failed:" << status << endl;
}
int main(int argc, char* argv[])
{
    {
        QApplication a(argc, argv);
        qtExample::MainWindow w;
        w.show();

        return a.exec();
    }


    std::chrono::steady_clock::time_point start_stitch = std::chrono::steady_clock::now();
    int retval = parseCmdArgs(argc, argv);
    if (retval) return -1;

    Mat pano;
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);

    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << int(status) << endl;
        return -1;
    }

    imwrite(result_name, pano);

    std::chrono::steady_clock::time_point end_end_stitch = std::chrono::steady_clock::now();

    std::cout << "Stitching took: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_end_stitch - start_stitch).count() << " ms" << std::endl;
    return 0;
}
Exemple #7
0
int main() {
    vector<Mat> images;

    // Read images 
    for(directory_iterator i(DATA_FOLDER_5), end_iter; i != end_iter; i++) {
        string im_name = i->path().filename().string();
        string filename = string(DATA_FOLDER_5) + im_name;
        Mat im = imread(filename);
        if(!im.empty()) 
            images.push_back(im);
    }

    cout << "Read " << images.size() << " images" << endl << "Now making panorama..." << endl;

    Mat panorama;

    Stitcher stitcher = Stitcher::createDefault();
    stitcher.stitch(images, panorama);

    namedWindow("Panorama", CV_WINDOW_NORMAL);
    imshow("Panorama", panorama);

    while(char(waitKey(1)) != 'q') {}

    return 0;
}
bool stitch (const cv::vector <cv::Mat> & images, cv::Mat &result) {
    Stitcher stitcher = Stitcher::createDefault(false);//don't need gpu
    Stitcher::Status status = stitcher.stitch(images, result);
    
    if (status != Stitcher::OK) {
        return false;
    }
    return true;
}
void VideoProcessor::Init(std::string filename)
{
	///生成全景图
	cv::VideoCapture cap;
	cap.open(filename);
	if (!cap.isOpened())
	{
		std::cout << "全景图-视频打开失败!" << std::endl;
		return ;
	}
	cv::Mat frame;//存储当前帧
	std::vector<cv::Mat> backImages;//存储背景的子图
	int count = 0;
	while (true)
	{
		++count;
		cap.read(frame);
		if (frame.empty())
		{
			std::cout << "全景图-图像读取失败" << std::endl;
			return;
		}

		if (count > 600 && ( count==650||count % 100 == 1 || count == 1152) && count < 1200)
		//if (count==5||count==370||count==400||count==445||count==490||count==540||count==600)
		{
			backImages.push_back(frame.clone());
		}
		if (count >= 1200)
		{
			break;
		}
	}
	std::cout << "子图个数:" << backImages.size() << "--- 正在生成全景图..." << std::endl;
	Stitcher stitcher = Stitcher::createDefault(false);
	Stitcher::Status status = stitcher.stitch(backImages, m_pano);
	if (status != Stitcher::OK)
	{
		cout << "全景图-Can't stitch images, error code=" << int(status) << endl;
		return ;
	}
	cv::cvtColor(m_pano, m_pano, cv::COLOR_BGR2GRAY);
	std::cout << "全景图生成成功!" << "全景图尺寸:" << m_pano.cols << "*" << m_pano.rows<<std::endl;
	cv::imshow("pano", m_pano);
	cv::waitKey();
	cv::destroyAllWindows();

	///提取全景图特征
	keyPointMatch.Set_trainImage(m_pano);
	std::cout << "提取全景图特征成功!" << std::endl;

	///初始化ViBe背景模型
	vibe_bgs.init(m_pano,frame);
	vibe_bgs.processFirstFrame(m_pano);
	std::cout << "初始化ViBe背景模型成功!" << std::endl;
	return ;
}
int main(int argc, char** argv){
    _left = Mat::zeros(480, 640, CV_8UC4);
    _right = Mat::zeros(480, 640, CV_8UC4);
    string outputWindow = "output";
    string leftWindow = "left";
    string rightWindow = "right";    

    ros::init(argc, argv, "image_stitcher_node");
    ros::NodeHandle nh;
    Mat output;
    namedWindow("output");
    
    Stitcher stitcher = Stitcher::createDefault(true);
    
    bool transformSet = false;
 
    image_transport::ImageTransport it(nh);
    image_transport::Subscriber left_sub = it.subscribe("/left_camera/image_raw", 2, leftCallback);
    image_transport::Subscriber right_sub = it.subscribe("/right_camera/image_raw", 2, rightCallback);    
    ros::Rate loop_rate(100);

    while(nh.ok()){
        vector<Mat> images;
        images.push_back(_left);
        images.push_back(_right);
        /*if (!transformSet){
            Stitcher::Status transform_status = stitcher.estimateTransform(images);
            if (transform_status == Stitcher::OK){
                transformSet = true;
                ROS_INFO("Transform Obtained");
            }
        }*/


                
        Stitcher::Status status = stitcher.stitch(images, output);
        images.clear();

        if (status != Stitcher::OK){
            ROS_ERROR("Unable to stitch");
        } else {
            imshow(outputWindow, output);
        }
        //imshow(leftWindow, _left);
        //imshow(rightWindow, _right);
        if (waitKey(10) == 27){
            break;
        }
        loop_rate.sleep();
        ros::spinOnce();
    }
} 
Exemple #11
0
void Stitch::on_actionStitch_triggered()
{
    Stitcher stitcher = Stitcher::createDefault(false);
    Stitcher::Status status = stitcher.stitch(imgs, result);
    if(status == Stitcher::OK)
    {
        Mat rgb;
        cvtColor(result,rgb,CV_BGR2RGB);
        ui->imageLabel->setPixmap(QPixmap::fromImage(QImage(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888)));
        ui->imageLabel->resize(ui->imageLabel->pixmap()->size());
        ui->scrollAreaWidgetContents->setFixedSize(ui->imageLabel->size());
    }
}
cv::Mat stitch (vector<Mat>& images)
{
    imgs = images;
    Mat pano;
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);
    
    if (status != Stitcher::OK)
        {
        cout << "Can't stitch images, error code = " << int(status) << endl;
            //return 0;
        }
    return pano;
}
Exemple #13
0
Mat stitch(vector<Mat> &imgs) {

    Mat stitched;
    Stitcher stitcher = Stitcher::createDefault(false);
    Stitcher::Status status = stitcher.stitch(imgs, stitched);

    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << int(status) << endl;
        //return -1;
    }

    imwrite(result_name, stitched);
    return stitched;
}
Exemple #14
0
cv::Mat stitch1 (vector<Mat>& images)
{
    imgs = images;
    Mat pano;
    Mat test;
    //test = imread("aa.jpg");
    //imshow("a",test);
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);
    
    if (status != Stitcher::OK)
        {
        cout << "Can't stitch images, error code = " << int(status) << endl;
            //return 0;
        }
    return pano;
}
int main(int argc, char* argv[])
{
    int retval = parseCmdArgs(argc, argv);
    if (retval) return -1;

    Mat pano;
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);

    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << int(status) << endl;
        return -1;
    }

    imwrite(result_name, pano);
    return 0;
}
float checkMultithreaded (string const & myResult, string const & learning)
{
    ofstream cmpLog("compare_log.txt", ofstream::trunc);
    if (!cmpLog.is_open())
    {
        cerr << "Cannot create compare_log file.\n";
        return 0;
    }

    map<int, vector<int> > myOdds = readOutput(myResult);
    map<int, vector<int> > trueOdds = readOutput(learning);

    int currentSetN = StartSet;
    int n_wrong = 0;
    float mark = 0;

    Stitcher stitcher;

    while (currentSetN < FinishSet)
    {
        vector<int> v1 = getNextSet(currentSetN, myOdds);
        vector<int> v2 = getNextSet(currentSetN, trueOdds);
        float tmpMark = compareResults(v1, v2);
        if (tmpMark != 1.0)
        {
            cmpLog << currentSetN << "\nmy odds:";
            printIntVector(cmpLog, v1);
            cmpLog << "true odds:";
            printIntVector(cmpLog, v2);

            int tmp;
            printMat_(cmpLog, stitcher.calcSetStitch2(currentSetN, &tmp));
            //Stitcher::printStitchMatrix(cmpLog, stitcher.calcSetStitch2(currentSetN));

            n_wrong += 1;

        }
        mark += tmpMark;
        currentSetN += 1;
    }
    cmpLog << n_wrong << " classified wrong.";
    cmpLog.close();
    return (currentSetN-StartSet>0) ? mark/(currentSetN-StartSet) : mark;
}
Exemple #17
0
int main()
{
/*
    Mat img = imread(IMAGE_PATH_PREFIX + "part5.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part1.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part8.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part3.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part6.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part4.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part7.jpg");
    imgs.push_back(img);
    img=imread(IMAGE_PATH_PREFIX+"part2.jpg");
    imgs.push_back(img);
*/
    Mat img;
    for (auto i = 1; i < 4; ++i) {
      std::string path = "t" + std::to_string(i) + ".jpg";
      std::cout << "add: " + path << std::endl;
      img = imread(path);
      imgs.push_back(img);
    }

    Mat pano;
    //Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher stitcher = Stitcher::createDefault();
    Stitcher::Status status = stitcher.stitch(imgs, pano);

    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << int(status) << endl;
        return -1;
    }

    imwrite(result_name, pano);
    return 0;
}
Exemple #18
0
int main(int argc, char *argv[])
{
    vector<Mat> imgSource;
    Mat imgResult;

    imgSource.push_back(imread("./stitching_img/mat1.png"));
    imgSource.push_back(imread("./stitching_img/mat2.png"));
    imgSource.push_back(imread("./stitching_img/mat3.png"));
    imgSource.push_back(imread("./stitching_img/mat4.png"));
    imgSource.push_back(imread("./stitching_img/mat5.png"));
    imgSource.push_back(imread("./stitching_img/mat6.png"));
    imgSource.push_back(imread("./stitching_img/mat7.png"));

    Stitcher stitcher = Stitcher::createDefault(false);

    unsigned long t0, tFinal;

    // Start time
    t0 = getTickCount();

    // Actual stitching
    Stitcher::Status status = stitcher.stitch(imgSource, imgResult);

    // End time
    tFinal = getTickCount();
    std::cout << (tFinal - t0)/getTickFrequency() << std::endl;

    if (status == Stitcher::OK) {
        // Save stitched image as png
        vector<int> paramsPNG;
        paramsPNG.push_back(CV_IMWRITE_PNG_COMPRESSION);
        paramsPNG.push_back(9);

        imwrite("mat0.png", imgResult, paramsPNG);

        std::cout << "Map stitcher: OK." << std::endl;
    } else {
        std::cout << "Map stitcher: NO OK." << std::endl;
    }

    return 0;
}
Exemple #19
0
int main(int argc, char* argv[])
{
	if (argc < 2)
	{
		printf("usage: %s path/folder/contains/images the_output_image=\"result.png\" \n", argv[0]);
		return -1;
	}

	string folder = argv[1];
	if (argc == 3)
		result_name = argv[2];
	
	ofxDirList DIR;
	DIR.allowExt("png");
	DIR.allowExt("jpg");
	int n_images = DIR.listDir(folder);
	for (int i=0;i<n_images;i++)
	{
		Mat raw = imread(DIR.getPath(i));
		if (!raw.empty())
		{
			imgs.push_back(raw);
		}
	}

    Mat pano;
    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);

    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << status << endl;
        return -1;
    }

    imwrite(result_name, pano);
	imshow(result_name, pano);

	waitKey();

    return 0;
}
Exemple #20
0
OCL_PERF_TEST_P(stitch, b12, TEST_DETECTORS)
{
    UMat pano;

    vector<Mat> imgs;
    imgs.push_back( imread( getDataPath("stitching/b1.png") ) );
    imgs.push_back( imread( getDataPath("stitching/b2.png") ) );

    Ptr<detail::FeaturesFinder> featuresFinder = getFeatureFinder(GetParam());
    Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb"
            ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE)
            : makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);

    declare.iterations(20);

    while(next())
    {
        Stitcher stitcher = Stitcher::createDefault();
        stitcher.setFeaturesFinder(featuresFinder);
        stitcher.setFeaturesMatcher(featuresMatcher);
        stitcher.setWarper(makePtr<SphericalWarper>());
        stitcher.setRegistrationResol(WORK_MEGAPIX);

        startTimer();
        stitcher.stitch(imgs, pano);
        stopTimer();
    }

    EXPECT_NEAR(pano.size().width, 1124, 50);
    EXPECT_NEAR(pano.size().height, 644, 30);

    SANITY_CHECK_NOTHING();
}
Exemple #21
0
OCL_PERF_TEST_P(stitch, boat, TEST_DETECTORS)
{
    Size expected_dst_size(10789, 2663);
    checkDeviceMaxMemoryAllocSize(expected_dst_size, CV_16SC3, 4);

#if defined(_WIN32) && !defined(_WIN64)
    if (cv::ocl::useOpenCL())
        throw ::perf::TestBase::PerfSkipTestException();
#endif

    UMat pano;

    vector<Mat> _imgs;
    _imgs.push_back( imread( getDataPath("stitching/boat1.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat2.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat3.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat4.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat5.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat6.jpg") ) );
    vector<UMat> imgs = ToUMat(_imgs);

    Ptr<detail::FeaturesFinder> featuresFinder = getFeatureFinder(GetParam());
    Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb"
            ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE)
            : makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);

    declare.iterations(20);

    while(next())
    {
        Stitcher stitcher = Stitcher::createDefault();
        stitcher.setFeaturesFinder(featuresFinder);
        stitcher.setFeaturesMatcher(featuresMatcher);
        stitcher.setWarper(makePtr<SphericalWarper>());
        stitcher.setRegistrationResol(WORK_MEGAPIX);

        startTimer();
        stitcher.stitch(imgs, pano);
        stopTimer();
    }

    EXPECT_NEAR(pano.size().width, expected_dst_size.width, 200);
    EXPECT_NEAR(pano.size().height, expected_dst_size.height, 100);

    SANITY_CHECK_NOTHING();
}
OCL_PERF_TEST_P(stitch, boat, TEST_DETECTORS)
{
    UMat pano;

    vector<Mat> _imgs;
    _imgs.push_back( imread( getDataPath("stitching/boat1.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat2.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat3.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat4.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat5.jpg") ) );
    _imgs.push_back( imread( getDataPath("stitching/boat6.jpg") ) );
    vector<UMat> imgs = ToUMat(_imgs);

    Ptr<detail::FeaturesFinder> featuresFinder = GetParam() == "orb"
            ? Ptr<detail::FeaturesFinder>(new detail::OrbFeaturesFinder())
            : Ptr<detail::FeaturesFinder>(new detail::SurfFeaturesFinder());

    Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb"
            ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE)
            : makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);

    declare.iterations(20);

    while(next())
    {
        Stitcher stitcher = Stitcher::createDefault();
        stitcher.setFeaturesFinder(featuresFinder);
        stitcher.setFeaturesMatcher(featuresMatcher);
        stitcher.setWarper(makePtr<SphericalWarper>());
        stitcher.setRegistrationResol(WORK_MEGAPIX);

        startTimer();
        stitcher.stitch(imgs, pano);
        stopTimer();
    }

    EXPECT_NEAR(pano.size().width, 10789, 200);
    EXPECT_NEAR(pano.size().height, 2663, 100);

    SANITY_CHECK_NOTHING();
}
Exemple #23
0
PERF_TEST_P(stitch, b12, TEST_DETECTORS)
{
    Mat pano;

    vector<Mat> imgs;
    imgs.push_back( imread( getDataPath("stitching/b1.png") ) );
    imgs.push_back( imread( getDataPath("stitching/b2.png") ) );

    Ptr<detail::FeaturesFinder> featuresFinder = GetParam() == "orb"
            ? Ptr<detail::FeaturesFinder>(new detail::OrbFeaturesFinder())
            : Ptr<detail::FeaturesFinder>(new detail::SurfFeaturesFinder());

    Ptr<detail::FeaturesMatcher> featuresMatcher = GetParam() == "orb"
            ? makePtr<detail::BestOf2NearestMatcher>(false, ORB_MATCH_CONFIDENCE)
            : makePtr<detail::BestOf2NearestMatcher>(false, SURF_MATCH_CONFIDENCE);

    declare.time(30 * 20).iterations(20);

    while(next())
    {
        Stitcher stitcher = Stitcher::createDefault();
        stitcher.setFeaturesFinder(featuresFinder);
        stitcher.setFeaturesMatcher(featuresMatcher);
        stitcher.setWarper(makePtr<SphericalWarper>());
        stitcher.setRegistrationResol(WORK_MEGAPIX);

        startTimer();
        stitcher.stitch(imgs, pano);
        stopTimer();
    }

    Mat pano_small;
    if (!pano.empty())
        resize(pano, pano_small, Size(320, 240), 0, 0, INTER_AREA);

    SANITY_CHECK(pano_small, 5);
}
int main(int argc, char **argv)	{
	ros::init(argc, argv, NODE_NAME, ros::init_options::NoSigintHandler);
	signal(SIGINT, onShutdown);
	
	if(!connectToCamera(cap1) || !connectToCamera(cap2) || !connectToCamera(cap3)){
		ROS_FATAL("Unable to connect to all cameras, exiting now");
		ROS_FATAL("If this error persist, run the usb-reset.sh in the home directory");
		return 0;
	}
	
	Mat image1, image2, image3;		
	std::vector<Mat> imgs;
	Stitcher stitcher = Stitcher::createDefault(true);

	int counter = 0;
	int errorCounter = 0;
	bool retry = false;
	namedWindow(CVWINDOW);	
	//ros::Duration(1).sleep();	//Give some time for the camera to warm up

	while (ros::ok() && errorCounter < 5){
		ROS_INFO("Image Stitching Started!");
		counter++;
		
		/*
		When reading from the camera, there is a chance of an error occuring.
		However these aren't OpenCV errors, so a try/catch block is useless :(

		This error will produce the following messages on the terminal
			libv4l2: error queuing buf 0: No such device
			libv4l2: error queuing buf 1: No such device
			libv4l2: error dequeuing buf: No such device
			VIDIOC_DQBUF: No such device
		and in the next iteration, the following error messages is printed before crashing
			libv4l2: error dequeuing buf: No such device
			VIDIOC_DQBUF: No such device
			Segmentation fault(core dumped)
		*/
			
		if (!cap1.read(image1)){
			ROS_WARN("Cannot read image 1 from video stream");
			errorCounter++;
			continue;
		}
		if (!cap2.read(image2)){
			ROS_WARN("Cannot read image 2 from video stream");
			errorCounter++;
			continue;
		}
		if (!cap3.read(image3)){
			ROS_WARN("Cannot read image 3 from video stream");
			errorCounter++;
			continue;
		}
	
		if (image1.empty() || image2.empty() || image3.empty())
			ROS_WARN("One of the Mat is empty");

		//Delcaring the @pano inside the loop seems to significantly decrease
		//the chance of an error happening. Perhaps there's some old data that
		//wasn't properly destroyed...
		Mat pano;
		imgs.push_back(image1);
		imgs.push_back(image2);
		imgs.push_back(image3);

		Stitcher::Status status= stitcher.stitch(imgs, pano);
		imgs.clear();
		
		if (status != Stitcher::OK) {
			ROS_FATAL("Unable to stitch images together!, trying again...");
			continue;

		} else {			    
			ROS_INFO("Awaiting for stiched image to display");
			imshow(CVWINDOW, pano);
			if(waitKey(25) == 27){
				ROS_INFO("ESC key pressed! Exiting loop now");
				ROS_WARN("The next run has a higher chance of crashing for unknown reasons");
				break;
	       	}
		}
		ROS_INFO("Iteration: %d", counter);
	}

	onShutdown(0);	
	return 0;
}
int main()  
{

// Load the images
VideoCapture cap1(1); 
VideoCapture cap2(2); 
VideoCapture cap3(3);

for(;;)
{
	Mat image1;
	cap1 >> image1; // get a new frame from camera

	Mat image2;
	cap2 >> image2; // get a new frame from camera
	
	Mat image3;
	cap3 >> image3; // get a new frame from camera
	
	imshow("first image",image1);
	cv::imwrite("./data/Image1.jpg", image1);
	
	imshow("second image",image2);
	cv::imwrite("./data/Image2.jpg", image2);
	
	imshow("third image",image3);
	cv::imwrite("./data/Image3.jpg", image3);
	
	if( !image1.data || !image2.data || !image3.data )
	 { std::cout<< " --(!) Error reading images " << std::endl; return -1; }
	

	vector< Mat > vImg;
	Mat rImg;

	vImg.push_back( image1 );
	vImg.push_back( image2 );
	vImg.push_back( image3 );
	  

	Stitcher stitcher = Stitcher::createDefault();


	unsigned long AAtime=0, BBtime=0; //check processing time
	AAtime = getTickCount(); //check processing time

	Stitcher::Status status = stitcher.stitch(vImg, rImg);

	BBtime = getTickCount(); //check processing time 
	printf("%.2lf sec \n",  (BBtime - AAtime)/getTickFrequency() ); //check processing time

	if (Stitcher::OK == status) 
	{
	  imshow("Result",rImg);
	  cv::imwrite("./Result/stitching_result.jpg", rImg);
	}
	else
	  printf("Stitching fail.");

	if(waitKey(30) >= 0) break;
	else usleep(2000000);
	// waitKey(0);

}
}  
Stitcher Stitcher::createDefault(bool try_use_gpu)
{
    Stitcher stitcher;
    stitcher.setRegistrationResol(0.6);
    stitcher.setSeamEstimationResol(0.1);
    stitcher.setCompositingResol(ORIG_RESOL);
    stitcher.setPanoConfidenceThresh(1);
    stitcher.setWaveCorrection(true);
    stitcher.setWaveCorrectKind(detail::WAVE_CORRECT_HORIZ);
    stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(try_use_gpu));
    stitcher.setBundleAdjuster(new detail::BundleAdjusterRay());

#ifdef HAVE_OPENCV_GPU
    if (try_use_gpu && gpu::getCudaEnabledDeviceCount() > 0)
    {
#ifdef HAVE_OPENCV_NONFREE
        stitcher.setFeaturesFinder(new detail::SurfFeaturesFinderGpu());
#else
        stitcher.setFeaturesFinder(new detail::OrbFeaturesFinder());
#endif
        stitcher.setWarper(new SphericalWarperGpu());
        stitcher.setSeamFinder(new detail::GraphCutSeamFinderGpu());
    }
    else
#endif
    {
#ifdef HAVE_OPENCV_NONFREE
        stitcher.setFeaturesFinder(new detail::SurfFeaturesFinder());
#else
        stitcher.setFeaturesFinder(new detail::OrbFeaturesFinder());
#endif
        stitcher.setWarper(new SphericalWarper());
        stitcher.setSeamFinder(new detail::GraphCutSeamFinder(detail::GraphCutSeamFinderBase::COST_COLOR));
    }

    stitcher.setExposureCompensator(new detail::BlocksGainCompensator());
    stitcher.setBlender(new detail::MultiBandBlender(try_use_gpu));

    return stitcher;
}