main.cpp

Nikolay Rogoshchenkov, 2013-07-12 03:47 pm

Download (9.6 kB)

 
1
2
#include <iostream>
3
#include <fstream>
4
#include "opencv2/highgui/highgui.hpp"
5
#include "opencv2/stitching/stitcher.hpp"
6
#include "opencv/cv.h"
7
#include "opencv2/gpu/gpu.hpp"
8
9
#include <time.h>
10
#include <windows.h>                // for Windows APIs
11
using namespace std;
12
using namespace std;
13
using namespace cv;
14
using namespace cv::gpu;
15
16
17
bool try_use_gpu = false;
18
vector<Mat> imgs;
19
string result_name = "result.tif";
20
21
void printUsage();
22
int parseCmdArgs(int argc, char** argv);
23
void lensCorrectorBarrel( unsigned char*, int, int);
24
25
int main(int argc, char* argv[])
26
{
27
28
        /*DeviceInfo info = getDevice();
29
        cout << info.name() << endl;*/
30
31
LARGE_INTEGER frequency;        // ticks per second
32
    LARGE_INTEGER t1, t2;           // ticks
33
    double elapsedTime;
34
35
QueryPerformanceFrequency(&frequency);
36
    int retval = parseCmdArgs(argc, argv);
37
    if (retval) return -1;
38
        printf("Images loaded.\n");
39
    Mat pano;
40
        
41
        printf("Channels image1: %d\n", imgs[0].type());
42
        printf("Channels image2: %d\n", imgs[1].type());
43
44
45
        int width = 170;
46
        cv::Rect rect1 = cvRect( imgs[0].cols-width, 0, width, imgs[0].rows); //second half of the first image
47
        cv::vector<cv::Rect> roi1;
48
        roi1.push_back(rect1);
49
50
51
        cv::Rect rect12 =  cvRect(0, 0,width, imgs[1].rows);  //first half of the second image
52
        cv::Rect rect23 = cvRect(imgs[1].cols -width, 0, width, imgs[1].rows);  //second half of the first image
53
        cv::vector<cv::Rect> roi2;
54
        roi2.push_back(rect12);
55
        roi2.push_back(rect23);
56
57
        cv::Rect rect34 =  cvRect(0, 0,width, imgs[2].rows);  //first half of the second image
58
        cv::Rect rect45 = cvRect(imgs[2].cols -width, 0, width, imgs[2].rows);  //second half of the first image
59
        cv::vector<cv::Rect> roi3;
60
        roi3.push_back(rect34);
61
        roi3.push_back(rect45);
62
63
        cv::Rect rect56 =  cvRect(0, 0,width, imgs[3].rows);  //first half of the second image
64
        cv::Rect rect67 = cvRect(imgs[3].cols -width, 0, width, imgs[3].rows);  //second half of the first image
65
        cv::vector<cv::Rect> roi4;
66
        roi4.push_back(rect56);
67
        roi4.push_back(rect67);
68
69
        cv::Rect rect78 =  cvRect(0, 0,width, imgs[4].rows);  //first half of the second image
70
        cv::Rect rect89 = cvRect(imgs[4].cols -width, 0, width, imgs[4].rows);  //second half of the first image
71
        cv::vector<cv::Rect> roi5;
72
        roi5.push_back(rect78);
73
        roi5.push_back(rect89);
74
75
        cv::Rect rect910 = cvRect(0, 0, width, imgs[5].rows); //first half of the third image
76
        cv::vector<cv::Rect> roi6;
77
        roi6.push_back(rect910);
78
79
80
81
        cv::vector<cv::vector<cv::Rect>> rois;
82
        rois.resize(6);
83
        rois[0] = roi1;
84
        rois[1] = roi2;
85
        rois[2] = roi3;
86
        rois[3] = roi4;
87
        rois[4] = roi5;
88
        rois[5] = roi6;
89
        //cv::imshow("debug_img1", imgs[0]);
90
        Mat tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
91
        cvtColor(imgs[0], tmp1, CV_BGR2GRAY); 
92
        cvtColor(imgs[1], tmp2, CV_BGR2GRAY); 
93
        cvtColor(imgs[2], tmp3, CV_BGR2GRAY); 
94
        cvtColor(imgs[3], tmp4, CV_BGR2GRAY); 
95
        cvtColor(imgs[4], tmp5, CV_BGR2GRAY); 
96
        cvtColor(imgs[5], tmp6, CV_BGR2GRAY); 
97
printf("ROI ready\n");
98
99
        lensCorrectorBarrel(tmp1.data, tmp1.cols, tmp1.rows);
100
        lensCorrectorBarrel(tmp2.data, tmp2.cols, tmp2.rows);
101
        lensCorrectorBarrel(tmp3.data, tmp3.cols, tmp3.rows);
102
        lensCorrectorBarrel(tmp4.data, tmp4.cols, tmp4.rows);
103
        lensCorrectorBarrel(tmp5.data, tmp5.cols, tmp5.rows);
104
        lensCorrectorBarrel(tmp6.data, tmp6.cols, tmp6.rows);
105
printf("Lens correction completed\n");
106
        imwrite("corr1.tif", tmp1);
107
        imwrite("corr2.tif", tmp2);
108
        imwrite("corr3.tif", tmp3);
109
        imwrite("corr4.tif", tmp4);
110
        imwrite("corr5.tif", tmp5);
111
        imwrite("corr6.tif", tmp6);
112
        /*namedWindow( "debug_img_corr1", CV_WINDOW_AUTOSIZE );
113
        namedWindow( "debug_img_corr2", CV_WINDOW_AUTOSIZE );
114
        cv::imshow("debug_img_corr1", tmp1);
115
        cv::imshow("debug_img_corr2", tmp2);*/
116
117
        cvtColor(tmp1, imgs[0], CV_GRAY2BGR); 
118
        cvtColor(tmp2, imgs[1], CV_GRAY2BGR); 
119
        cvtColor(tmp3, imgs[2], CV_GRAY2BGR); 
120
        cvtColor(tmp4, imgs[3], CV_GRAY2BGR); 
121
        cvtColor(tmp5, imgs[4], CV_GRAY2BGR);
122
        cvtColor(tmp6, imgs[5], CV_GRAY2BGR);
123
        //char cc = cvWaitKey(0);
124
125
        /*cv::rectangle( imgs[0], rect1, CV_RGB(255,0,0), 1);
126
        cv::rectangle( imgs[1], rect12, CV_RGB(255,0,0), 1);
127
        cv::rectangle( imgs[1], rect23, CV_RGB(255,0,0), 1);
128
        cv::rectangle( imgs[2], rect34, CV_RGB(255,0,0), 1);
129
        cv::rectangle( imgs[2], rect45, CV_RGB(255,0,0), 1);
130
        cv::rectangle( imgs[3], rect56, CV_RGB(255,0,0), 1);
131
        cv::rectangle( imgs[3], rect67, CV_RGB(255,0,0), 1);
132
        cv::rectangle( imgs[4], rect78, CV_RGB(255,0,0), 1);
133
        cv::rectangle( imgs[4], rect89, CV_RGB(255,0,0), 1);
134
        cv::rectangle( imgs[5], rect910, CV_RGB(255,0,0), 1);
135
        cv::imshow("debug_img1", imgs[0]);
136
        cv::imshow("debug_img2", imgs[1]);
137
        cv::imshow("debug_img3", imgs[2]);
138
        cv::imshow("debug_img4", imgs[3]);
139
        cv::imshow("debug_img5", imgs[4]);
140
        cv::imshow("debug_img6", imgs[5]);*/
141
        char c = cvWaitKey(0);
142
printf("Stitching started...\n");
143
        QueryPerformanceCounter(&t1);
144
    Stitcher stitcher = Stitcher::createDefault(false);
145
        //stitcher.setRegistrationResol(0.5);
146
        printf("registrationResol=%f\n", stitcher.registrationResol());
147
        //stitcher.setPanoConfidenceThresh(0.03);
148
        //stitcher.setWaveCorrection(false);
149
150
        //stitcher.setFeaturesMatcher(new cv::detail::BestOf2NearestMatcher(true));
151
        //detail::SurfFeaturesFinder *featureFinder = new detail::SurfFeaturesFinder(100);
152
        //stitcher.setFeaturesMatcher(matcher);
153
        //stitcher.setFeaturesFinder(featureFinder);
154
    Stitcher::Status status = stitcher.stitch(imgs, rois, pano);
155
        //Stitcher::Status status = stitcher.composePanorama(imgs, pano);
156
        
157
    if (status != Stitcher::OK)
158
    {
159
        cout << "Can't stitch images, error code = " << status << endl;
160
        return -1;
161
    }
162
163
164
QueryPerformanceCounter(&t2);
165
elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
166
        printf("%.6f ms",elapsedTime);
167
    imwrite(result_name, pano);
168
169
        char ac = cvWaitKey(0);
170
        if(ac == 'ESC')
171
                return 0;
172
}
173
174
175
void printUsage()
176
{
177
    cout <<
178
        "Rotation model images stitcher.\n\n"
179
        "stitching img1 img2 [...imgN]\n\n"
180
        "Flags:\n"
181
        "  --try_use_gpu (yes|no)\n"
182
        "      Try to use GPU. The default value is 'no'. All default values\n"
183
        "      are for CPU mode.\n"
184
        "  --output <result_img>\n"
185
        "      The default is 'result.jpg'.\n";
186
}
187
188
189
int parseCmdArgs(int argc, char** argv)
190
{
191
    if (argc == 1)
192
    {
193
        printUsage();
194
        return -1;
195
    }
196
    for (int i = 1; i < argc; ++i)
197
    {
198
        if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
199
        {
200
            printUsage();
201
            return -1;
202
        }
203
        else if (string(argv[i]) == "--try_gpu")
204
        {
205
            if (string(argv[i + 1]) == "no")
206
                try_use_gpu = true;
207
            else if (string(argv[i + 1]) == "yes")
208
                try_use_gpu = true;
209
            else
210
            {
211
                cout << "Bad --try_use_gpu flag value\n";
212
                return -1;
213
            }
214
            i++;
215
        }
216
        else if (string(argv[i]) == "--output")
217
        {
218
            result_name = argv[i + 1];
219
            i++;
220
        }
221
        else
222
        {
223
            Mat img = imread(argv[i]);
224
            if (img.empty())
225
            {
226
                cout << "Can't read image '" << argv[i] << "'\n";
227
                return -1;
228
            }
229
            imgs.push_back(img);
230
        }
231
    }
232
    return 0;
233
}
234
235
236
237
238
void lensCorrectorBarrel( unsigned char *pixels, int cols, int rows)
239
{
240
        unsigned char *pixelsCopy;
241
        pixelsCopy = (unsigned char *)malloc( cols * rows );
242
        memcpy( (char*) pixelsCopy, (char*)pixels, cols*rows);
243
244
        
245
        // parameters for correction
246
247
        //for one good lense
248
   /* double paramA = 0.0; // affects only the outermost pixels of the image
249
    double paramB = -0.000000062; // most cases only require b optimization
250
    double paramC = -0.0000020; // most uniform correction
251
    double paramD = 1.0120;// - paramA - paramB - paramC; // describes the linear scaling of the image
252
 */
253
        //for Edmundoptics 58201
254
        double paramA = 0.0; // affects only the outermost pixels of the image
255
    double paramB = -0.000000150; // most cases only require b optimization
256
    double paramC = -0.0000085; // most uniform correction
257
    double paramD = 1.04400;// - paramA - paramB - paramC; // describes the linear scaling of the image
258
259
260
    // center of dst image
261
    double centerX = (cols - 1) / 2.0;
262
    double centerY = (rows - 1) / 2.0;   
263
    
264
        #pragma omp parallel for
265
    for(int x = 0; x < cols; x++) {
266
        for(int y = 0; y < rows; y++) {
267
                int dstX = x;
268
            int dstY = y;
269
            // difference between center and point
270
            double diffX = centerX - dstX;
271
            double diffY = centerY - dstY;
272
//            printf("diffX=%f\n", diffX);
273
            // distance or radius of dst image
274
            double dstR = sqrt(diffX * diffX + diffY * diffY);
275
276
            // distance or radius of src image (with formula)
277
            double srcR = dstR*(paramA * dstR * dstR * dstR + paramB * dstR * dstR + paramC * dstR + paramD);
278
279
            // comparing old and new distance to get factor
280
            double factor =fabs( srcR / dstR);
281
            // coordinates in source image
282
            double srcXd = centerX + (diffX * factor);
283
            double srcYd = centerY + (diffY * factor);
284
                        
285
            // no interpolation yet (just nearest point)
286
            int srcX = floor(srcXd+0.5);
287
            int srcY = floor(srcYd+0.5);     
288
            if(srcX >= 0 && srcY >= 0 && srcX < cols && srcY < rows) {
289
                int dstPos = dstY * cols + dstX;
290
                pixels[cols * rows -dstPos] = pixelsCopy[srcY * cols + srcX];
291
            }       
292
        }
293
    }
294
        free (pixelsCopy);
295
}