bytedeco / sample-projects

Sample project files for JavaCPP, JavaCPP Presets, and JavaCV
218 stars 173 forks source link

OutOfMemoryError #36

Closed monxarat closed 6 years ago

monxarat commented 6 years ago

java.lang.OutOfMemoryError: Physical memory usage is too high: physicalBytes = 384M > maxPhysicalBytes = 384M

saudet commented 6 years ago

Use android:largeHeap="true": https://developer.android.com/guide/topics/manifest/application-element

monxarat commented 6 years ago

Hi @saudet I think therein is not the problem, this is the problem in codes.

screenshot from 2018-07-04 10-44-48

Video infor:

Dimension: 540x960 Size: 1.4MB

saudet commented 6 years ago

Ok, so it looks like you're trying to store too many images in memory. Don't do that?

monxarat commented 6 years ago

Hi @saudet No, I have not any changed code in this sample project.

saudet commented 6 years ago

Ok, might be an issue with the project, which one would that be?

monxarat commented 6 years ago

@saudet Do you have any sample with opencv_videostab?

saudet commented 6 years ago

I don't think so, but it shouldn't be too hard to adapt this C++ sample: https://github.com/opencv/opencv/blob/master/samples/cpp/videostab.cpp Let me know if you encounter any issues translating this and I will help! Thanks

monxarat commented 6 years ago

@saudet Thank you very much.

I have written some codes, but in the SDK have not GoodFeaturesToTrackDetector(I using openCV 4.0) class.

int nkps = 1000;
        Ptr<GoodFeaturesToTrackDetector> freatureDetector = makePtr<GoodFeaturesToTrackDetector>(nkps);
//third, create the motion estimator
        Ptr<KeypointBasedMotionEstimator> motionEstBuilder = makePtr<KeypointBasedMotionEstimator>(est);
        motionEstBuilder->setDetector(freatureDetector);

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

I will try to convert it to java.

monxarat commented 6 years ago

Hi @saudet I have written some code below, but when I ran the error bellow has occurred.

E/cv::error(): OpenCV Error: No Error (can't open file: /storage/emulated/0/DCIM/Camera/patio.mp4) in virtual void cv::videostab::{anonymous}::VideoFileSourceImpl::reset(), file /home/saudet/projects/bytedeco/javacpp-presets/opencv/cppbuild/android-arm/opencv-3.2.0/modules/videostab/src/frame_source.cpp, line 71

In my codes:

....
mFrameSource = new IFrameSource();
            // 1 prepare the input video and check it string input
            mVideoFileSource = new VideoFileSource(sourceVideo); // **error here**
            Log.d(">>>stab", "Frames Count: " + mVideoFileSource.count());

            // 2 prepare the motion estimator
            // first prepare the motion the estimation builder RANSAC L2;
            MotionEstimatorRansacL2 est = new MotionEstimatorRansacL2(opencv_videostab.MM_AFFINE);

            // set ransac params for motion estimator
            RansacParams ransacParams = est.ransacParams();
            ransacParams.size(RANSAC_SIZE);
            ransacParams.thresh(RANSAC_THRESH);
            ransacParams.eps(RANSAC_ESP);
....

frame_source.cpp, line 71

class VideoFileSourceImpl : public IFrameSource
{
public:
    VideoFileSourceImpl(const String &path, bool volatileFrame)
        : path_(path), volatileFrame_(volatileFrame) { reset(); }

    virtual void reset() CV_OVERRIDE
    {
#ifdef HAVE_OPENCV_VIDEOIO
        vc.release();
        vc.open(path_);
        if (!vc.isOpened())
            CV_Error(0, "can't open file: " + path_);**>>> LINE 71**
#else
        CV_Error(Error::StsNotImplemented, "OpenCV has been compiled without video I/O support");
#endif

I have refer #277, but no resolved for me.

saudet commented 6 years ago

Right, it's not being linked with FFmpeg, but we probably want more freedom than that anyway, so try to implement an IFrameSource. It should work fine with something like this:

IFrameSource frameSource = new IFrameSource() {
    @Override public void reset() { ... }
    @Override public Mat nextFrame() { ... };
}
monxarat commented 6 years ago

@saudet Since there are so many classes related to it, I think to implement it is difficult. You cant explain for me how to implement IFrameSource.

screenshot from 2018-07-12 18-03-52

and StabilizerBase public native void setFrameSource(@Ptr IFrameSource val);

saudet commented 6 years ago

I just gave you the code, what error are you getting with that code?

monxarat commented 6 years ago

@saudet thank you for your supporte

In my code, how to use the snippet code below.

...
mFrameSource = new IFrameSource(); **Replace here**
...
mVideoFileSource = VideoFileSource()// **this class extend from IFrameSource**
...
because stabilizer.setFrameSource(mVideoFileSource)

implement

IFrameSource frameSource = new IFrameSource() {
    @Override public void reset() { ... }
    @Override public Mat nextFrame() { ... };
}

My codes

/**
 * Created by chinhnq on 7/12/18.
 *
 * Video Stabilization
 */
public class VideoStabilization {

    private static final float MIN_INLIER_RATIO = 0.1f;
    private static final int RANSAC_SIZE = 3;
    private static final int RANSAC_THRESH = 5;
    private static final float RANSAC_ESP = 0.5f;
    private static final int NKPS = 1000;
    private static final boolean TWO_PASS = true;

    /** radius using for gaussian filter */
    private static final int RADIUS_PASS = 15;

    /** trim frame after stabilized */
    private static final boolean EST_TRIM = true;

    private static final boolean INCLUSION = false;
    private static final float TRIM_RATIO = 0.1f;
    private static final int STAB_RADIUS = 15;

    private static final int OUT_FPS = 25;

    /** stored frame of the video */
    private IFrameSource mFrameSource;
    private VideoFileSource mVideoFileSource;

    /** source video */
    private String sourceVideo;

    /** destination of the video*/
    private String destVideo;

    public VideoStabilization(String sourcePath, String destPath) {
        this.sourceVideo = sourcePath;
        this.destVideo = destPath;
    }

    public void stabilizer() {
        try{

            mFrameSource = new IFrameSource(); **Replace here**
            // 1 prepare the input video and check it string input
            mVideoFileSource = new VideoFileSource(sourceVideo);
            Log.d(">>>stab", "Frames Count: " + mVideoFileSource.count());

            // 2 prepare the motion estimator
            // first prepare the motion the estimation builder RANSAC L2;
            MotionEstimatorRansacL2 est = new MotionEstimatorRansacL2(opencv_videostab.MM_AFFINE);

            // set ransac params for motion estimator
            RansacParams ransacParams = est.ransacParams();
            ransacParams.size(RANSAC_SIZE);
            ransacParams.thresh(RANSAC_THRESH);
            ransacParams.eps(RANSAC_ESP);

            est.setRansacParams(ransacParams);
            est.setMinInlierRatio(MIN_INLIER_RATIO);

            // seconds, create a feature detector
            GFTTDetector feature = GFTTDetector.create();

            // third, create the motion estimator
            KeypointBasedMotionEstimator motionEstBuilder = new KeypointBasedMotionEstimator(est);
            motionEstBuilder.setDetector(feature);

            // define error
            IOutlierRejector outlierRejector = new IOutlierRejector(new NullOutlierRejector());
            motionEstBuilder.setOutlierRejector(outlierRejector);

            // 3 - Prepare stabilizer
            StabilizerBase stabilizer;

            // with a two pass stabilizer
            if (TWO_PASS) {
                TwoPassStabilizer twopass = new TwoPassStabilizer();
                twopass.setEstimateTrimRatio(EST_TRIM);
                twopass.setMotionStabilizer(new GaussianMotionFilter());

                stabilizer = twopass;
            } else {
                OnePassStabilizer onePass = new OnePassStabilizer();
                onePass.setMotionFilter(new GaussianMotionFilter());

                stabilizer = onePass;
            }

            // seconds, setup parameter
            stabilizer.setFrameSource(mVideoFileSource);
            stabilizer.setMotionEstimator(motionEstBuilder);
            stabilizer.setRadius(STAB_RADIUS);
            stabilizer.setTrimRatio(TRIM_RATIO);
            stabilizer.setCorrectionForInclusion(INCLUSION);
            stabilizer.setBorderMode(1);//BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`

            mFrameSource.reset();

            // 4-Processing the stabilized frames. The results are showed and saved.
            processing(mFrameSource, destVideo);
        }catch (Exception e) {
            e.printStackTrace();
            mFrameSource.close();
        }
    }

    private void processing(IFrameSource frameSource, String outpath) {
        if (frameSource == null || outpath.isEmpty())
            throw new IllegalArgumentException("IFrameSource and Out Path can't be null");

        Log.d(">>>stab", "Started");
        VideoWriter videoWriter = new VideoWriter();
        Mat stabilizedFrame;
        int nFrames = 0;

        //for each stabilized frame
        while (!(stabilizedFrame = frameSource.nextFrame()).empty()) {
            nFrames++;
            //init write one and save stabilized fame;
            if (!videoWriter.isOpened()) {
                videoWriter.open(outpath, VideoWriter.fourcc(
                        Byte.valueOf("M"),
                        Byte.valueOf("P"),
                        Byte.valueOf("4"),
                        Byte.valueOf("S")), OUT_FPS, stabilizedFrame.size());
            }
            Log.d(">>>stab", "Frame: " + nFrames);
            videoWriter.write(stabilizedFrame);
        }

        Log.d(">>>stab", "Processed Frames: " + nFrames);
        Log.d(">>>stab", "Finished");
    }
}

I have written this code in C++ using NDK (JNI) but when I ran, the same error occurred? Why? 07-13 18:38:39.986 16554-16554/com.xxx.3x E/cv::error(): OpenCV(3.4.1) Error: No Error (can't open file: /storage/emulated/0/DCIM/Camera/patio.mp4) in virtual void cv::videostab::{anonymous}::VideoFileSourceImpl::reset(), file /build/master_pack-android/opencv/modules/videostab/src/frame_source.cpp, line 71

saudet commented 6 years ago

Replace it with copy/paste...? or what do you mean?

The file error is probably because you didn't give access permission to the application.

monxarat commented 6 years ago

@saudet

Replace it with copy/paste...? or what do you mean?

No, I do not understand how to implement it.

The file error is probably because you didn't give access permission to the application.

I have set permission read file.

saudet commented 6 years ago

Looks like you need to read up on Java a bit, read this page from the tutorial: https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

monxarat commented 6 years ago

@saudet My problem not how to implement Anonymous Classes, that my problem is in the code of the two methods nextFrame() and reset().

IFrameSource frameSource = new IFrameSource() {
    @Override public void reset() { 
<how to do this>

}
    @Override public Mat nextFrame() { 
<how to do this>
};
}
saudet commented 6 years ago

That's for you to decide, where are your images?

monxarat commented 6 years ago

@saudet

where are your images?

I don't understand what you mean.

saudet commented 6 years ago

Where is your video?

monxarat commented 6 years ago

@saudet

/storage/emulated/0/DCIM/Camera/patio.mp4

saudet commented 6 years ago

Ok, we could do something like this:

IFrameSource frameSource = new IFrameSource() {
    FrameGrabber grabber = new FFmpegFrameGrabber("/storage/emulated/0/DCIM/Camera/patio.mp4");
    OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
    @Override public void reset() { grabber.restart(); }
    @Override public Mat nextFrame() { return converter.convert(grabber.grabImage()); }
};
monxarat commented 6 years ago

@saudet Thank you very much. is run very well. But slow.

In code C++ I have using (*) `stabilizerFrame.reset(dynamic_cast<IFrameSource>(stabilizer));`

stabilizer = twoPassStabilizer;

        //seconds, setup parameter
        stabilizer->setFrameSource(source);
        stabilizer->setMotionEstimator(motionEstBuilder);
        stabilizer->setRadius(RADIUS_STAB);
        stabilizer->setTrimRatio(TRIM_RATIO);
        stabilizer->setCorrectionForInclusion(INCL_CONTR);
        stabilizer->setBorderMode(BORDER_REPLICATE);

        // cast stabilizer to single frame source interface to read stabilized frames
        stabilizerFrame.reset(dynamic_cast<IFrameSource*>(stabilizer));

        // 4-Processing the stabilized frames. The results are showed and saved.
        process(stabilizerFrame, outPath);

In the code (**) corresponding to in the Java.

monxarat commented 6 years ago

@saudet In code C++, we can using cv::resze(Mat src, Mat des);

But in Java code can't use it.

Mat scaleImage = new Mat();
scaleImage.create(new opencv_core.Size(mOutImgSize.getWidth(), mOutImgSize.getHeight()), IPL_DEPTH_8U);
(*)cvResize(outImagePrev, scaleImage); 

(*) -> public static native void cvResize( @Const CvArr src, CvArr dst);

I don't want to convert Mat to IplImage (improved performance).

saudet commented 6 years ago

@monxarat Call resize(), not cvResize().

monxarat commented 6 years ago

@saudet Thank you very much. Thank you for your support.

In code C++ I have using (*) `stabilizerFrame.reset(dynamic_cast<IFrameSource>(stabilizer));`

C++ code:

stabilizer = twoPassStabilizer;

        //seconds, setup parameter
        stabilizer->setFrameSource(source);
        stabilizer->setMotionEstimator(motionEstBuilder);
        stabilizer->setRadius(RADIUS_STAB);
        stabilizer->setTrimRatio(TRIM_RATIO);
        stabilizer->setCorrectionForInclusion(INCL_CONTR);
        stabilizer->setBorderMode(BORDER_REPLICATE);

        // cast stabilizer to single frame source interface to read stabilized frames
        stabilizerFrame.reset(dynamic_cast<IFrameSource*>(stabilizer));**Here**
       /// this line in the Java code?

        // 4-Processing the stabilized frames. The results are showed and saved.
        process(stabilizerFrame, outPath);

Java Code

// seconds, setup parameter
            stabilizer.setFrameSource(mFrameSource);
            stabilizer.setMotionEstimator(motionEstBuilder);
            stabilizer.setRadius(STAB_RADIUS);
            stabilizer.setTrimRatio(TRIM_RATIO);
            stabilizer.setCorrectionForInclusion(INCLUSION);
            stabilizer.setBorderMode(1);//BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`

            mFrameSource.reset();** how to handle? **

            // 4-Processing the stabilized frames. The results are showed and saved.
            processing(mFrameSource, destVideo);

In the code (**) corresponding to in the Java, This snippet code I do not understand (I think to wrap FrameSource and Frame after stabilized? Right)

saudet commented 6 years ago

Yes, try to use an object created like I showed you above: https://github.com/bytedeco/sample-projects/issues/36#issuecomment-405022098

monxarat commented 6 years ago

@saudet How to do this. I do not understand (dubious :-() I have using mFrameSource = stabilizer.asIFrameSource(); but error

After stabilized, mFrameSource.reset() and usingstabilizer.asIFrameSource() get stabilization frames. But when called nextFrame() method ,error has occurred -> return frame null.

saudet commented 6 years ago

What error do you get?

monxarat commented 6 years ago
// seconds, setup parameter
stabilizer.setFrameSource(mFrameSource);
stabilizer.setMotionEstimator(motionEstBuilder);
stabilizer.setRadius(STAB_RADIUS);
stabilizer.setTrimRatio(TRIM_RATIO);
stabilizer.setCorrectionForInclusion(INCLUSION);
stabilizer.setBorderMode(1);//BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`

mFrameSource = stabilizer.asIFrameSource();
mFrameSource.reset();

// 4-Processing the stabilized frames. The results are showed and saved.
processing(mFrameSource, destVideo);

Logs

07-19 20:20:12.372 9711-10144/com.vizo360.sport W/System.err: org.bytedeco.javacv.FrameGrabber$Exception: Could not grab: No AVFormatContext. (Has start() been called?)
        at org.bytedeco.javacv.FFmpegFrameGrabber.grabFrame(FFmpegFrameGrabber.java:634)
        at org.bytedeco.javacv.FFmpegFrameGrabber.grab(FFmpegFrameGrabber.java:621)
        at org.bytedeco.javacv.FrameGrabber.grabFrame(FrameGrabber.java:444)
        at com.example.VideoStabilization$VizoFrameSource.nextFrame(VideoStabilization.java:238)
        at org.bytedeco.javacpp.opencv_videostab$IFrameSource.nextFrame(Native Method)
        at com.example.VideoStabilization.processing(VideoStabilization.java:151)
        at com.example.VideoStabilization.stabilizer(VideoStabilization.java:131)
        at com.example.extract.VideoExtractor.extractVideo(VideoExtractor.java:320)
07-19 20:24:21.976 11210-11577/com.vizo360.sport E/javacpp: Return pointer address is NULL in callback for org.bytedeco.javacpp.opencv_videostab.IFrameSource.

07-19 20:24:22.154 11210-11577/com.vizo360.sport E/cv::error(): OpenCV Error: Assertion failed (ssize.width > 0 && ssize.height > 0) in void cv::resize(cv::InputArray, cv::OutputArray, cv::Size, double, double, int), file /home/saudet/projects/bytedeco/javacpp-presets/opencv/cppbuild/android-arm/opencv-3.2.0/modules/imgproc/src/imgwarp.cpp, line 3492
07-19 20:24:22.155 11210-11577/com.vizo360.sport W/System.err: java.lang.RuntimeException: /home/saudet/projects/bytedeco/javacpp-presets/opencv/cppbuild/android-arm/opencv-3.2.0/modules/imgproc/src/imgwarp.cpp:3492: error: (-215) ssize.width > 0 && ssize.height > 0 in function void cv::resize(cv::InputArray, cv::OutputArray, cv::Size, double, double, int)
        at org.bytedeco.javacpp.opencv_imgproc.resize(Native Method)
        at com.example.VideoStabilization.processing(VideoStabilization.java:160)
        at com.example.VideoStabilization.stabilizer(VideoStabilization.java:131)
        at com.example.extract.VideoExtractor.extractVideo(VideoExtractor.java:320)
        at com.example.extract.VideoExtractor.startExtract(VideoExtractor.java:426)
        at com.example.extract.VideoExtractor.access$000(VideoExtractor.java:45)
        at com.example.extract.VideoExtractor$ExtractionWorker.run(VideoExtractor.java:251)
07-19 20:24:22.156 11210-11577/com.vizo360.sport W/System.err:     at java.lang.Thread.run(Thread.java:818)
saudet commented 6 years ago

Ah, it looks like we'll need to call start() on grabber just after creating it.

monxarat commented 6 years ago

@saudet

I have created class MyFrameSource

static class MyFrameSource extends IFrameSource {
        private FrameGrabber mFrameGrabber;
        private OpenCVFrameConverter.ToMat mConverter;

        MyFrameSource(String sourceVideo) {
            mFrameGrabber = new FFmpegFrameGrabber(sourceVideo);
            mConverter = new OpenCVFrameConverter.ToMat();

            start();//<<<--- Call start here
        }

        @Override
        public Mat nextFrame() {...}

        @Override
        public void reset() {...}
    }
Called 
IFrameSource mFrameSource = new MyFrameSource(sourceVideo);

    ...

    // 3 - Prepare stabilizer
    TwoPassStabilizer stabilizer = new TwoPassStabilizer();

    // seconds, setup parameter
    stabilizer.setFrameSource(mFrameSource);
    stabilizer.setMotionEstimator(motionEstBuilder);
    stabilizer.setRadius(STAB_RADIUS);
    stabilizer.setTrimRatio(TRIM_RATIO);
    stabilizer.setCorrectionForInclusion(INCLUSION);
    stabilizer.setBorderMode(1);//BORDER_REPLICATE   = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`

    mFrameSource = stabilizer.asIFrameSource();
    mFrameSource.reset();

    // 4-Processing the stabilized frames. The results are showed and saved.
    processing(mFrameSource, destVideo);

Before called start() after call reset() run is OK, but duplicate process.

saudet commented 6 years ago

Great! Please consider sending a pull request to add your sample.

monxarat commented 6 years ago

@saudet This example has a problem I talk above. I call start() (*) in of the MyFrameSource constructor. and after assign stabilized frames of the TwoPassStabilizer object to mFrameSource (mFrameSource = stabilizer.asIFrameSource()) and call mFrameSource.reset().

The while loop in the processing(mFrameSource, destVideo) method only called when then (*) has finished.

The processing time doubled. How to call start() or reset() only.

saudet commented 6 years ago

We can call restart() after start(), that's not an issue.

monxarat commented 6 years ago

@saudet I Will improvement in performance after.

when calling frameSource = stabilizer.asIFrameSource() method . In this method have a while loop. In the asIFrameSource method, How to save Frame to an Image when creating an IFrameSource in the asIFrameSource method. Because have some case want to save Frame after stabilized.

saudet commented 6 years ago

You're talking about imwrite() I think?

monxarat commented 6 years ago

yes, but I want to save Frame in the asIFrameSource in the TwoPassStabilizer. Can I do that?

saudet commented 6 years ago

Yeah, why not?

monxarat commented 6 years ago

I can't request create a new pull. create_pull

saudet commented 6 years ago

You'll need to create a fork first: https://help.github.com/articles/working-with-forks/

monxarat commented 6 years ago

I have created a project on my Github and add remote to sample-projects. but I can't perform step 5 in the link

screenshot from 2018-07-23 12-34-56

monxarat commented 6 years ago

yes, but I want to save Frame in the asIFrameSource in the TwoPassStabilizer. Can I do that?

Yeah, why not?

How to do this.

saudet commented 6 years ago

With imwrite() I guess. What error message do you get when trying?

2018年7月23日(月) 15:37 monxarat notifications@github.com:

yes, but I want to save Frame in the asIFrameSource in the TwoPassStabilizer. Can I do that?

Yeah, why not?

How to do this.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bytedeco/sample-projects/issues/36#issuecomment-406954983, or mute the thread https://github.com/notifications/unsubscribe-auth/ADLIF0APPNndOrltU-nCe9TPQn5SPgIlks5uJW89gaJpZM4VAvjw .

monxarat commented 6 years ago

No, In my code I have using imwrite to write an image is ok. But, this step after stabilized. I want to save the image when asIFrameSource running.

When call stabilizer.asIFrameSource()

// 3 - Prepare stabilizer
TwoPassStabilizer stabilizer = new TwoPassStabilizer();

// seconds, setup parameter
stabilizer.setFrameSource(mFrameSource);
stabilizer.setMotionEstimator(motionEstBuilder);
stabilizer.setRadius(mMyVideoStabConfig.getStabRadius());
stabilizer.setTrimRatio(mMyVideoStabConfig.getStabTrimRatio());
stabilizer.setCorrectionForInclusion(mMyVideoStabConfig.isInclusion());
stabilizer.setBorderMode(mMyVideoStabConfig.getBorderTypes().value());
mFrameSource = stabilizer.asIFrameSource();
mFrameSource.reset();

// 4-Processing the stabilized frames. The results are showed and saved.
processing(mFrameSource, destVideo);

nextFrame() method will be run.

static class MyFrameSource extends IFrameSource {
        @Override
        public Mat nextFrame() {...}

        @Override
        public void reset() {...}
    }

When stabilizer.asIFrameSource();I to save an Image in the method processing(mFrameSource, destVideo).

private void processing(IFrameSource frameSource, String outpath) {
        if (frameSource == null || outpath.isEmpty())
            throw new IllegalArgumentException("IFrameSource and Out Path can't be null");

        try {
            VideoWriter videoWriter = new VideoWriter();

            Log.d(">>>stab", "Started");
            Mat stabilizedFrame = null;
            int nFrames = 0;

            final int maxFrame = frameGrabber.getLengthInFrames();
            final int[] params = new int[]{opencv_imgcodecs.IMWRITE_JPEG_PROGRESSIVE, 0, opencv_imgcodecs.IMWRITE_JPEG_OPTIMIZE, 0, opencv_imgcodecs.IMWRITE_JPEG_QUALITY, Config.COMPRESS_QUALITY};

            //for each stabilized frame
            while (nFrames < maxFrame) {
                stabilizedFrame = frameSource.nextFrame();
                if (stabilizedFrame != null && !stabilizedFrame.empty()) {
                    nFrames++;

                    if (!videoWriter.isOpened()) {
                        videoWriter.open(outpath + "/stanbilized.avi",
                                VideoWriter.fourcc(
                                        ((byte) 'M'),
                                        ((byte) 'J'),
                                        ((byte) 'P'),
                                        ((byte) 'G')),
                                MyVideoStabConfig.OUT_FPS,
                                new opencv_core.Size(stabilizedFrame.rows(), stabilizedFrame.cols()));

                    }

                    // rotate mat, because when capture video has rotated corresponding
                    // with the device orientation and font/back camera.
                    stabilizedFrame = rotate(rotateVideo, stabilizedFrame);

                    // resize image
                    Mat dest = new Mat();
                    //resize(outImagePrev, dest, new opencv_core.Size(mOutImgSize.getWidth(), mOutImgSize.getHeight()));

                    // save to disk
                    String outputFile = String.format(Locale.US, "%s/%s", outpath, String.format(Locale.ENGLISH, Config.IN_FRAME_FORMAT, nFrames));
                    opencv_imgcodecs.imwrite(outputFile, stabilizedFrame, params);

                    videoWriter.write(stabilizedFrame);

                    // release
                    stabilizedFrame.release();
                    dest.release();

                    Log.e(">>>IFrameSource", "Loop: " + nFrames);
                }
            }

            try {
                stabilizedFrame.release();
                frameGrabber.release();
            } catch (FrameGrabber.Exception e) {
                e.printStackTrace();
            }
        } catch (Exception ex){
            ex.printStackTrace();
        }
    }
saudet commented 6 years ago

Do you mean, how to use FFmpegFrameRecorder?

monxarat commented 6 years ago

No, I want to save Frame to Image in the stabilizer.asIFrameSource() method of the TwoPassStabilizer class. --> How to do this?

The current, I save Frame to Image follow code. But I do not want using this code. because of it very slow.

the current codes. ↓

IFrameSource mFrameSource = IFrameSource {
        @Override
        public Mat nextFrame() {...}
        @Override
        public void reset() {...}
    }
....
TwoPassStabilizer stabilizer = new TwoPassStabilizer();
stabilizer.setFrameSource(mFrameSource);
....
mFrameSource = stabilizer.asIFrameSource(); //**→called called nextFrame() of the 
                                                                        // IFrameSource class above: While loop
                                                                        //I want to save Frames to Images in here.**
mFrameSource.reset();
...
// Processing the stabilized frames. The results are showed and saved.
processing(mFrameSource, destVideo);

...

implement processing method ↓

private void processing(IFrameSource frameSource, String outpath) {
            //for each stabilized frame
            while (nFrames < maxFrame) {
            /// save frame here... -->>> **I do not want to save frame to Image here.**
                }
    }
saudet commented 6 years ago

Well, writing image files is slow...

monxarat commented 6 years ago

Is there a way to make it?

saudet commented 6 years ago

They are many ways. Saving your images uncompressed or using an accelerator are probably the easiest thing to try.