Ejemplo n.º 1
0
int main(int argc, char *argv[]) {
  opterr = 0;

  int width = -1;
  int height = -1;
  int max_frames = -1;
  const char *in = NULL;
  const char *out = NULL;
  bool time = false;
  int stripType = Blend::STRIP_TYPE_THIN;

  const struct option long_options[] = {
    {"width",  required_argument, 0, 'w'},
    {"height", required_argument, 0, 'h'},
    {"in",     required_argument, 0, 'i'},
    {"out",    required_argument, 0, 'o'},
    {"strip",  required_argument, 0, 's'},
    {"max",    required_argument, 0, 'm'},
    {"time",   no_argument      , 0, 't'},
    {0,        0,                 0, 0}
  };

  int c;

  if (argc == 1) {
    usage();
    return 0;
  }

  while (1) {
    c = getopt_long(argc, argv, "w:h:i:o:s:m:t", long_options, NULL);
    if (c == -1) {
      break;
    }

    switch (c) {
    case 'w':
      width = atoi(optarg);
      break;

    case 'h':
      height = atoi(optarg);
      break;

    case 'i':
      in = optarg;
      break;

    case 'o':
      out = optarg;
      break;

    case 't':
      time = true;
      break;

    case 's':
      stripType = atoi(optarg);
      break;

    case 'm':
      max_frames = atoi(optarg);
      break;

    case '?':
      usage();
      return 0;
    }
  }

  // validate
  if (width <= 0) {
    std::cerr << "invalid width " << width << std::endl;
    return 1;
  }

  if (height <= 0) {
    std::cerr << "invalid height " << height << std::endl;
    return 1;
  }

  if (!in) {
    std::cerr << "input file not provided" << std::endl;
    return 1;
  }

  if (!out) {
    std::cerr << "output file not provided" << std::endl;
    return 1;
  }

  if (stripType < 0 || stripType > 1) {
    std::cerr << "invalid strip type " << stripType << std::endl;
    return 1;
  }

  // input
  int fd = open(in, O_RDONLY);
  if (fd == -1) {
    perror("open");
    return 1;
  }


  int size = (width * height * 12) / 8;

  std::cout << "input width = " << width << ", height = " << height << std::endl;
  std::cout << "strip type: " << stripType << " (" << strips[stripType] << ")" << std::endl;

  int frames = count_frames(fd, size);

  if (frames == -1) {
    close(fd);
    return 1;
  }

  if (max_frames > 0) {
    frames = MIN(frames, max_frames);
  }

  // initialize our mosaicer
  Mosaic m;
  if (!m.initialize(blendingType, stripType, width, height, frames, true, 5.0f)) {
    std::cerr << "Failed to initialize mosaicer" << std::endl;
    close(fd);
    return 1;
  }

  std::vector<int> times;
  std::vector<unsigned char *> mosaic_frames;
  unsigned char *in_data = NULL;

  for (int x = 0; x < frames; x++) {
    // allocate:
    if (!in_data) {
      in_data = new unsigned char[size];
    }

    if (read(fd, in_data, size) == size) {
      // process
      int time = timeNow();
      int ret = m.addFrame(in_data);
      time = timeNow() - time;

      times.push_back(time);

      if (ret == Mosaic::MOSAIC_RET_OK || ret == Mosaic::MOSAIC_RET_FEW_INLIERS) {
	mosaic_frames.push_back(in_data);
	in_data = NULL;
      }
    } else {
      break;
    }
  }

  if (in_data) {
    delete[] in_data;
  }

  close(fd);

  std::cout << "Used " << mosaic_frames.size() << " frames" << std::endl;

  // output
  // TODO: what are those?
  float progress = 0;
  bool cancel = false;

  int64_t stitchingTime = timeNow();

  if (m.createMosaic(progress, cancel) != Mosaic::MOSAIC_RET_OK) {
    std::cerr << "Failed to stitch" << std::endl;
    return 1;
  }

  stitchingTime = timeNow() - stitchingTime;

  ImageType yuv = m.getMosaic(width, height);
  ImageType rgb = ImageUtils::allocateImage(width, height, 3);
  ImageUtils::yvu2rgb(rgb, yuv, width, height);

  for (int x = 0; x < mosaic_frames.size(); x++) {
    delete[] mosaic_frames[x];
  }

  mosaic_frames.clear();

  bool res = write_png(out, rgb, width, height);
  ImageUtils::freeImage(rgb);
  if (!res) {
    return 1;
  }

  std::cout << "Wrote mosaic image to " << out << std::endl;
  std::cout << "Width = " << width << " height = " << height << std::endl;

  if (time) {
    std::cout << "Average frame time = " << std::accumulate(times.begin(), times.end(), 0) / times.size() << "ms" << std::endl;
    std::cout << "Final stitching time = " << stitchingTime << "ms" << std::endl;
  }

  return 0;
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
    struct timespec t1, t2, t3;

    int width, height;
    float totalElapsedTime = 0;

    const char *basename;
    const char *filename;

    if (argc != 3) {
        printf("Usage: %s input_dir output_filename\n", argv[0]);
        return 0;
    } else {
        basename = argv[1];
        filename = argv[2];
    }

    // Load the images outside the computational kernel
    int totalFrames = loadImages(basename, width, height);

    if (totalFrames == 0) {
        printf("Image files not found. Make sure %s exists.\n",
               basename);
        return 1;
    }

    printf("%d frames loaded\n", totalFrames);


    // Interesting stuff is here
    for (int iteration = 0; iteration < KERNEL_ITERATIONS; iteration++)  {
        Mosaic mosaic;

        mosaic.initialize(blendingType, stripType, width, height, -1, false, 0);

        clock_gettime(CLOCK_MONOTONIC, &t1);
        for (int i = 0; i < totalFrames; i++) {
            mosaic.addFrame(yvuFrames[i]);
        }
        clock_gettime(CLOCK_MONOTONIC, &t2);

        float progress = 0.0;
        bool cancelComputation = false;

        mosaic.createMosaic(progress, cancelComputation);

        int mosaicWidth, mosaicHeight;
        ImageType resultYVU = mosaic.getMosaic(mosaicWidth, mosaicHeight);

        ImageType imageRGB = ImageUtils::allocateImage(
            mosaicWidth, mosaicHeight, ImageUtils::IMAGE_TYPE_NUM_CHANNELS);

        clock_gettime(CLOCK_MONOTONIC, &t3);

        float elapsedTime =
            (t3.tv_sec - t1.tv_sec) + (t3.tv_nsec - t1.tv_nsec)/1e9;
        float addImageTime =
            (t2.tv_sec - t1.tv_sec) + (t2.tv_nsec - t1.tv_nsec)/1e9;
        float stitchImageTime =
            (t3.tv_sec - t2.tv_sec) + (t3.tv_nsec - t2.tv_nsec)/1e9;

        totalElapsedTime += elapsedTime;

        printf("Iteration %d: %dx%d moasic created: "
               "%.2f seconds (%.2f + %.2f)\n",
               iteration, mosaicWidth, mosaicHeight,
               elapsedTime, addImageTime, stitchImageTime);

        // Write the output only once for correctness check
        if (iteration == 0) {
            ImageUtils::yvu2rgb(imageRGB, resultYVU, mosaicWidth,
                                mosaicHeight);
            ImageUtils::writeBinaryPPM(imageRGB, filename, mosaicWidth,
                                       mosaicHeight);
        }
    }
    printf("Total elapsed time: %.2f seconds\n", totalElapsedTime);

    return 0;
}