Home | History | Annotate | Download | only in panorama
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <time.h>
     18 #include <sys/types.h>
     19 #include <sys/stat.h>
     20 #include <unistd.h>
     21 
     22 #include "mosaic/Mosaic.h"
     23 #include "mosaic/ImageUtils.h"
     24 
     25 #define MAX_FRAMES 200
     26 #define KERNEL_ITERATIONS 10
     27 
     28 const int blendingType = Blend::BLEND_TYPE_HORZ;
     29 const int stripType = Blend::STRIP_TYPE_WIDE;
     30 
     31 ImageType yvuFrames[MAX_FRAMES];
     32 
     33 int loadImages(const char* basename, int &width, int &height)
     34 {
     35     char filename[512];
     36     struct stat filestat;
     37     int i;
     38 
     39     for (i = 0; i < MAX_FRAMES; i++) {
     40         sprintf(filename, "%s_%03d.ppm", basename, i + 1);
     41         if (stat(filename, &filestat) != 0) break;
     42         ImageType rgbFrame = ImageUtils::readBinaryPPM(filename, width, height);
     43         yvuFrames[i] = ImageUtils::allocateImage(width, height,
     44                                 ImageUtils::IMAGE_TYPE_NUM_CHANNELS);
     45         ImageUtils::rgb2yvu(yvuFrames[i], rgbFrame, width, height);
     46         ImageUtils::freeImage(rgbFrame);
     47     }
     48     return i;
     49 }
     50 
     51 int main(int argc, char **argv)
     52 {
     53     struct timespec t1, t2, t3;
     54 
     55     int width, height;
     56     float totalElapsedTime = 0;
     57 
     58     const char *basename;
     59     const char *filename;
     60 
     61     if (argc != 3) {
     62         printf("Usage: %s input_dir output_filename\n", argv[0]);
     63         return 0;
     64     } else {
     65         basename = argv[1];
     66         filename = argv[2];
     67     }
     68 
     69     // Load the images outside the computational kernel
     70     int totalFrames = loadImages(basename, width, height);
     71 
     72     if (totalFrames == 0) {
     73         printf("Image files not found. Make sure %s exists.\n",
     74                basename);
     75         return 1;
     76     }
     77 
     78     printf("%d frames loaded\n", totalFrames);
     79 
     80 
     81     // Interesting stuff is here
     82     for (int iteration = 0; iteration < KERNEL_ITERATIONS; iteration++)  {
     83         Mosaic mosaic;
     84 
     85         mosaic.initialize(blendingType, stripType, width, height, -1, false, 0);
     86 
     87         clock_gettime(CLOCK_MONOTONIC, &t1);
     88         for (int i = 0; i < totalFrames; i++) {
     89             mosaic.addFrame(yvuFrames[i]);
     90         }
     91         clock_gettime(CLOCK_MONOTONIC, &t2);
     92 
     93         float progress = 0.0;
     94         bool cancelComputation = false;
     95 
     96         mosaic.createMosaic(progress, cancelComputation);
     97 
     98         int mosaicWidth, mosaicHeight;
     99         ImageType resultYVU = mosaic.getMosaic(mosaicWidth, mosaicHeight);
    100 
    101         ImageType imageRGB = ImageUtils::allocateImage(
    102             mosaicWidth, mosaicHeight, ImageUtils::IMAGE_TYPE_NUM_CHANNELS);
    103 
    104         clock_gettime(CLOCK_MONOTONIC, &t3);
    105 
    106         float elapsedTime =
    107             (t3.tv_sec - t1.tv_sec) + (t3.tv_nsec - t1.tv_nsec)/1e9;
    108         float addImageTime =
    109             (t2.tv_sec - t1.tv_sec) + (t2.tv_nsec - t1.tv_nsec)/1e9;
    110         float stitchImageTime =
    111             (t3.tv_sec - t2.tv_sec) + (t3.tv_nsec - t2.tv_nsec)/1e9;
    112 
    113         totalElapsedTime += elapsedTime;
    114 
    115         printf("Iteration %d: %dx%d moasic created: "
    116                "%.2f seconds (%.2f + %.2f)\n",
    117                iteration, mosaicWidth, mosaicHeight,
    118                elapsedTime, addImageTime, stitchImageTime);
    119 
    120         // Write the output only once for correctness check
    121         if (iteration == 0) {
    122             ImageUtils::yvu2rgb(imageRGB, resultYVU, mosaicWidth,
    123                                 mosaicHeight);
    124             ImageUtils::writeBinaryPPM(imageRGB, filename, mosaicWidth,
    125                                        mosaicHeight);
    126         }
    127     }
    128     printf("Total elapsed time: %.2f seconds\n", totalElapsedTime);
    129 
    130     return 0;
    131 }
    132