Video stabilization with videostab module [closed]

asked 2017-06-26 05:37:53 -0600

martisan gravatar image

Hi all,

Really hope that someone can assist with the following problem. I'm currently trying to video stabilization on iOS, but I'm getting an out of memory exception.

I have the following code that attempts to stabilize the video:

+ (int)videoStabFileAtURL:(NSURL *)inputURL writeToURL:(NSURL *)outputURL {
  Ptr<IFrameSource> stabilizedFrames;

  try {
    // 1 - Prepare input video and check it
    String inputPath = *new String(inputURL.path.UTF8String);
    String outputPath = *new String(outputURL.path.UTF8String);

    Ptr<VideoFileSource> source = makePtr<VideoFileSource>(inputPath);
    cout << "Frame count (rough): " << source->count() << endl;

    // 2 - Prepare the motion estimator
    double min_inlier_ratio = 0.1;

    Ptr<MotionEstimatorRansacL2> est = makePtr<MotionEstimatorRansacL2>(MM_TRANSLATION_AND_SCALE);
    RansacParams ransac = est->ransacParams();
    ransac.thresh = 5;
    ransac.eps = 0.5;

    est->setRansacParams(ransac);
    est->setMinInlierRatio(min_inlier_ratio);

    // 3 - Create a feature detector
    int nkps = 20;

    Ptr<GFTTDetector> feature_detector = GFTTDetector::create(nkps);

    // 4 - Create motion estimator
    Ptr<KeypointBasedMotionEstimator> motionEstBuilder = makePtr<KeypointBasedMotionEstimator>(est);
    motionEstBuilder->setDetector(feature_detector);

    Ptr<IOutlierRejector> outlierRejector = makePtr<NullOutlierRejector>();
    motionEstBuilder->setOutlierRejector(outlierRejector);

    // 5 - Prepare stabilizer
    StabilizerBase *stabilizer = 0;

    int radius_pass = 15;
    bool est_trim = true;

//    TwoPassStabilizer *twoPassStabilizer = new TwoPassStabilizer();
//    twoPassStabilizer->setEstimateTrimRatio(est_trim);
//    twoPassStabilizer->setMotionStabilizer(makePtr<GaussianMotionFilter>(radius_pass));

    OnePassStabilizer *onePassStabilizer = new OnePassStabilizer();
    onePassStabilizer->setMotionFilter(makePtr<GaussianMotionFilter>(radius_pass));

    stabilizer = onePassStabilizer;

    // Setup parameters
    int radius = 15;
    double trim_ratio = 0.1;
    bool incl_constr = false;

    stabilizer->setFrameSource(source);
    stabilizer->setMotionEstimator(motionEstBuilder);
    stabilizer->setRadius(radius);
    stabilizer->setTrimRatio(trim_ratio);
    stabilizer->setCorrectionForInclusion(incl_constr);
    stabilizer->setBorderMode(BORDER_REPLICATE);

    // Cast stabilizer to simple frame source interface to read stabilized frames
    stabilizedFrames.reset(dynamic_cast<IFrameSource*>(stabilizer));

    // 6 - Processing the stabilized frames. The results are saved
    processing(stabilizedFrames, outputPath);
  } catch (const exception &e) {
    cout << "Error: " << e.what() << endl;
    stabilizedFrames.release();
    return -1;
  }

  stabilizedFrames.release();
  return 0;
}

void processing(Ptr<IFrameSource> stabilizedFrames, String outputPath) {
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    @autoreleasepool {
      VideoWriter videoWriter;
      Mat stabilizedFrame;
      int nframes = 0;
      double outputFps = 30;

      // For each stabilized frame
      while (!(stabilizedFrame = stabilizedFrames->nextFrame()).empty()) {
        nframes++;

        // Init writer (once) and save stabilized frame
        if (!outputPath.empty()) {
          if (!videoWriter.isOpened()) {
            videoWriter.open(outputPath, VideoWriter::fourcc('H', '2', '6', '4'), outputFps, stabilizedFrame.size());
            videoWriter << stabilizedFrame;
          }
        }
      }
    }
  });
}

I can see it processing the frames, but it's using a lot of memory on an iPhone 6, which eventually leads to the app crashing. Does anyone know what I can do to reduce memory usage?

edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by sturkmen
close date 2020-10-08 10:25:10.117251