stitching.cpp 3.23 KB
Newer Older
1

2
#include "opencv2/imgcodecs.hpp"
3 4
#include "opencv2/highgui.hpp"
#include "opencv2/stitching.hpp"
5

6 7
#include <iostream>

8 9 10
using namespace std;
using namespace cv;

11
bool divide_images = false;
12
Stitcher::Mode mode = Stitcher::PANORAMA;
13 14 15
vector<Mat> imgs;
string result_name = "result.jpg";

16
void printUsage(char** argv);
17 18 19 20 21
int parseCmdArgs(int argc, char** argv);

int main(int argc, char* argv[])
{
    int retval = parseCmdArgs(argc, argv);
22
    if (retval) return EXIT_FAILURE;
23

24
    //![stitching]
25
    Mat pano;
26
    Ptr<Stitcher> stitcher = Stitcher::create(mode);
27
    Stitcher::Status status = stitcher->stitch(imgs, pano);
28 29 30

    if (status != Stitcher::OK)
    {
31
        cout << "Can't stitch images, error code = " << int(status) << endl;
32
        return EXIT_FAILURE;
33
    }
34
    //![stitching]
35 36

    imwrite(result_name, pano);
37
    cout << "stitching completed successfully\n" << result_name << " saved!";
38
    return EXIT_SUCCESS;
39 40 41
}


42
void printUsage(char** argv)
43 44
{
    cout <<
45 46 47
         "Images stitcher.\n\n" << "Usage :\n" << argv[0] <<" [Flags] img1 img2 [...imgN]\n\n"
         "Flags:\n"
         "  --d3\n"
48
         "      internally creates three chunks of each image to increase stitching success\n"
49 50 51 52 53 54
         "  --mode (panorama|scans)\n"
         "      Determines configuration of stitcher. The default is 'panorama',\n"
         "      mode suitable for creating photo panoramas. Option 'scans' is suitable\n"
         "      for stitching materials under affine transformation, such as scans.\n"
         "  --output <result_img>\n"
         "      The default is 'result.jpg'.\n\n"
55
         "Example usage :\n" << argv[0] << " --d3 --try_use_gpu yes --mode scans img1.jpg img2.jpg\n";
56 57 58 59 60 61 62
}


int parseCmdArgs(int argc, char** argv)
{
    if (argc == 1)
    {
63
        printUsage(argv);
64
        return EXIT_FAILURE;
65
    }
66

67 68 69 70
    for (int i = 1; i < argc; ++i)
    {
        if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
        {
71
            printUsage(argv);
72
            return EXIT_FAILURE;
73
        }
74 75 76 77
        else if (string(argv[i]) == "--d3")
        {
            divide_images = true;
        }
78
        else if (string(argv[i]) == "--output")
79 80 81 82
        {
            result_name = argv[i + 1];
            i++;
        }
83 84 85 86 87 88 89 90 91
        else if (string(argv[i]) == "--mode")
        {
            if (string(argv[i + 1]) == "panorama")
                mode = Stitcher::PANORAMA;
            else if (string(argv[i + 1]) == "scans")
                mode = Stitcher::SCANS;
            else
            {
                cout << "Bad --mode flag value\n";
92
                return EXIT_FAILURE;
93 94 95
            }
            i++;
        }
96
        else
97
        {
98 99
            Mat img = imread(argv[i]);
            if (img.empty())
100
            {
101
                cout << "Can't read image '" << argv[i] << "'\n";
102
                return EXIT_FAILURE;
103
            }
104 105 106 107 108 109 110 111 112 113 114 115

            if (divide_images)
            {
                Rect rect(0, 0, img.cols / 2, img.rows);
                imgs.push_back(img(rect).clone());
                rect.x = img.cols / 3;
                imgs.push_back(img(rect).clone());
                rect.x = img.cols / 2;
                imgs.push_back(img(rect).clone());
            }
            else
                imgs.push_back(img);
116 117
        }
    }
118
    return EXIT_SUCCESS;
119
}