Java library captures image with very slow rate [FPS]

asked 2016-11-27 01:42:28 -0500

A.Nemati gravatar image

updated 2016-11-29 02:11:30 -0500

I used opencv to capture image within my project which is written in Java and I used your java library to do so. Using this method, I can get 10 FPS only in 1280x720 resolution however when I capture image by your c++ library using the same camera, I can capture about 25 to 30 FPS with the same resolution, which is a huge and unbelievable difference.

What's the problem with the Java library and why it is so slower than the c++ library. Isn't it just a wrapper upon the native opencv or what ???

Please answer this question because our project have been stuck since this problem arised. I tried other wrapper libraries upon opencv also but unfortunately I got almost the same result.

Any hint or solution ???

This is my Code:

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;
import org.opencv.videoio.VideoWriter;

public class ConnectCamViaOpenCV {
    private VideoCapture videoCapture;
    private boolean isOpened;
    private boolean isSucceed;

    public ConnectCamViaOpenCV() {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        videoCapture = null;
        isOpened = false;
        isSucceed = false;
    }

    public void grabImage(){
        Mat frame = new Mat();

        //connect
        videoCapture = new VideoCapture(0);
        isOpened = videoCapture.isOpened();
        System.out.println("connected: " + isOpened());
        //setSetting
        videoCapture.set(Videoio.CV_CAP_PROP_FRAME_WIDTH, 1280);
        videoCapture.set(Videoio.CV_CAP_PROP_FRAME_HEIGHT, 720);
        //startGrab
        isSucceed = videoCapture.grab();
        System.out.println("started: " + String.valueOf(isSucceed));
        if ((!isOpened) || (!isSucceed))
            return;
        System.out.println("------- START GRAB -------");

        //Wait for camera starting
        while (true){
            videoCapture.read(frame);
            if (!frame.empty())
                break;
        }

        int frameNo = 0;
        long startSysMillis = System.currentTimeMillis();
        while (frameNo < 150){
            videoCapture.read(frame);
            frameNo++;
        }
        System.out.println(frameNo + " frames in " + (System.currentTimeMillis() - startSysMillis) + " millis");

        videoCapture.release(); // release device

        System.out.println('\n' + "Done");
    }

    public static void main(String[] args) {
        ConnectCamViaOpenCV connectCamViaOpenCV = new ConnectCamViaOpenCV();
        connectCamViaOpenCV.grabImage();
    }
}

The result is:

connected: true
started: true
------- START GRAB -------
150 frames in 16905 millis

Done
edit retag flag offensive close merge delete

Comments

demanding an answer won't work ever.

berak gravatar imageberak ( 2016-11-27 04:11:20 -0500 )edit

also, please show your code.

(problem might be in your processing, not the capture)

berak gravatar imageberak ( 2016-11-27 04:36:26 -0500 )edit

I put my code by edit question.

A.Nemati gravatar imageA.Nemati ( 2016-11-29 01:55:52 -0500 )edit

I got 150 frames in 4947 millis with your example on Ubuntu 16.04 with V4L backend and virtual webcam as source (v4l2loopback) and 1920x1080 resolution. Verified by writing each frame to PNG file.

mshabunin gravatar imagemshabunin ( 2016-12-01 04:05:20 -0500 )edit

thank you. but, please check with real camera, if you can. real camera has some delay. I tested this code on real camera and similar code with c++ on same camera.

A.Nemati gravatar imageA.Nemati ( 2016-12-19 01:37:35 -0500 )edit

Checked with Logitech HD720p camera (don't know exact model name) and it gives similar 150 frames in 5159 millis with 1280x720 resolution.

There should be no big difference between Java and C++ VideoCapture usage, because the wrapping code is rather thin. Check if there are differences in other things: platform (windows, linux, osx), video driver (v4l, gstreamer, ffmpeg, ...), OpenCV version (2.4, 3.x), build configuration (Debug, Release). In Java configuration info can be printed with System.out.println(Core.getBuildInformation());, in C++ - std::cout << cv::getBuildInformation() <<std:: endl;.

Or maybe you use some specific Java runtime or options or camera settings...

mshabunin gravatar imagemshabunin ( 2016-12-19 06:00:39 -0500 )edit