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?