Ask Your Question
0

videocapture reads the same frame differently on multiple calls

asked 2016-05-21 02:46:28 -0600

gaetano gravatar image

updated 2016-05-22 04:00:54 -0600

pklab gravatar image

Hi, I am new to the forum. I have started using Opencv with Java a few weeks ago. In my program I use videocapture to read frames from an avi file. Yesterday I have noticed that, over different runs of my progrem, the n-th frame read from the file is different from the same n-th frame read from the same file, in a previous run. I have confirmed this by subtracting two copies of the same frame, after resetting the video capture to the same frame number. Is this expected, or am I doing something wrong?

for (int j = 0; j < 100; j++){
    Mat img = new Mat();
    Mat m1 = new Mat();
    Mat m2 = new Mat();

    VideoCapture vc = new VideoCapture(filename);
    vc.set(Videoio.CAP_PROP_POS_FRAMES, 0);
    for (int i = 0; i < 9; i++) vc.grab();
    vc.read(img);
    m1 = img.clone();
    Imgproc.cvtColor(m1, m1, Imgproc.COLOR_BGR2GRAY);
    vc.release();

    vc = new VideoCapture(filename);
    vc.set(Videoio.CAP_PROP_POS_FRAMES, 0);
    for (int i = 0; i < 9; i++) vc.grab();
    vc.read(img);
    m2 = img.clone();
    Imgproc.cvtColor(m2, m2, Imgproc.COLOR_BGR2GRAY);
    vc.release();

    Mat m3 = new Mat();
    Core.absdiff(m1, m2, m3);

    if (Core.countNonZero(m3) > 0)System.out.println(Core.sumElems(m3));
}
edit retag flag offensive close merge delete

Comments

What if using 2 different capture obj like VideoCapture vc1 = new VideoCapture(filename) and VideoCapture vc2 = new VideoCapture(filename) ?

You should put both grab() and read() in the for loop and check if they returns true.

PS: please provide a bit of your code.. please next time update your question instead of add code using comments

pklab gravatar imagepklab ( 2016-05-21 04:05:55 -0600 )edit

In this code I am interested in extracting only the first frame from the video. The "grab" calls are in the two inner loops to make sure to exhaust what it seems to be a frame buffer in the VideoCapture object; the buffer size is 9 in my case, although I am not sure why that is. The outer loop is just to test the overall program multiple times. The output of the System.out is occasionally non-zero, for example 5-6 times over the 100 loop iterations. Instead I would expect it to be always zero, as essentially the program is reading the same first frame twice and, as such, the output of the absdiff should be zero.

gaetano gravatar imagegaetano ( 2016-05-23 07:33:09 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
0

answered 2016-05-24 09:32:59 -0600

gaetano gravatar image

It seems I have found a solution to my issue, although I am still not sure if that is the proper way to solve this: I have copied the "opencv_ffmpeg310_64.dll" file from the bin folder to my eclipse project. Now "differences" is indeed zero, always.

When I followed the guide on the Opencv website on how to integrate Opencv in Eclipse, nowhere it is mentioned to include also this dll.

...now I am wondering how did Opencv manage without that dll in the first place, without giving an error nor exception??? I am sure I do not have any other installations of ffmpeg on my pc. Any thoughts on this?

edit flag offensive delete link more

Comments

Did you install opencv using CMake?

LBerger gravatar imageLBerger ( 2016-05-24 13:17:16 -0600 )edit

no, in windows, i downloaded and extracted version 3.0 into my programs folder. i did not rebuild the opencv. and then i set up opencv in eclipse as described on the website. i did not get any error and it seemed to work fine for basic examples.

gaetano gravatar imagegaetano ( 2016-05-25 02:13:28 -0600 )edit

Do you have opencv in system variable PATH?

LBerger gravatar imageLBerger ( 2016-05-25 02:44:38 -0600 )edit

no i haven't. I have set up Opencv in Eclipse as described in http://docs.opencv.org/2.4/doc/tutori.... And the example in the guide works for me, so I assumed everything was fine.

gaetano gravatar imagegaetano ( 2016-05-26 04:57:41 -0600 )edit

So In foolder exe example have you got this dll? In folder where you have your exe file have you got this dll

LBerger gravatar imageLBerger ( 2016-05-26 09:03:40 -0600 )edit
0

answered 2016-05-23 13:17:21 -0600

pklab gravatar image

updated 2016-05-24 02:36:52 -0600

read() = grab() + retrieve() (check the doc) and I don't know what you get when 1 read() is following N grab() ...

Sorry but what happens using simple read() like below:

boolean ok1,ok2;

VideoCapture vc1 = new VideoCapture(filename);
// Thread.sleep(500L);    // file is loading, wait a bit
ok1 = vc1.read(m1);
vc1.release();

Thread.sleep(1000L);      // wait 1 one second to be sure the file has been released

VideoCapture vc2 = new VideoCapture(filename);
// Thread.sleep(500L);    // file is loading, wait a bit
ok2 =  vc2.read(m2);
vc2.release();

if(ok1 && ok2) {
    Mat m3 = new Mat();
    Core.absdiff(m1, m2, m3);
    int differences = Core.countNonZero(m3);
    System.out.println("Total differences: "+differences);
}
else System.out.println("Unable to load both frames");

ok1 (and/or ok2) can be false if 1st frame isn't ready as soon as the file has been opened. In this case try some sleep just before read()

EDIT: I think you are doing some mistake with loops and functions ... I don't have a java env ready but the C++ code below matches N frames with 0 difference on C++/x64/VS2013/Win7/OpenCV 3.1dev

Mat m1, m2, m3,m4;
bool ok1, ok2;
string filename = "C:/Users/xyz/Desktop/AVSS_AB_Easy_Divx.avi";
VideoCapture vc1(filename);
VideoCapture vc2(filename);
int N = 100;
for (int i = 0; i < N; i++) {
    ok1 = vc1.read(m1);
    ok2 = vc2.read(m2);
    if (ok1 && ok2) {
        absdiff(m1, m2, m3);
        cvtColor(m3, m4, CV_BGR2GRAY);
        int differences = countNonZero(m4);
        cout << "Total differences: " << differences << endl;
    }
    else cout << "Unable to load both frames" << endl;
}
edit flag offensive delete link more

Comments

i have tried your code (with small midifications: countNonZero gives me an error for a 3-channel image, so had to convert to grayscale): when i read the first frame, the difference is zero. But if i have 2 reads, i.e. i read first and second frame, than ok1 and ok2 are both true, but differences is non zero. I have tried to increase the sleep time, but it does not change anything. The video I am using now can be downloaded from ftp://motinas.elec.qmul.ac.uk/pub/iLids/ (the second in the list). It is like as if the decoding process of the frames introduce small artefacts. For example, in one run I get: Total differences: 23856 For a 720x576 video, this is an average of ~6% difference. So very small differences betwee the two images. I have never experienced the same problem in Matlab.

gaetano gravatar imagegaetano ( 2016-05-23 16:29:43 -0600 )edit

check edit in my answer

pklab gravatar imagepklab ( 2016-05-24 02:37:35 -0600 )edit

Thank you for your comments. Here is my java version of your suggested code:

    Mat m1 = new Mat(), m2 = new Mat(), m3 = new Mat(), m4 = new Mat();
    boolean ok1, ok2;

    String name = "avss.avi";
    String filename = System.getProperty("user.home") + "\\MyDataset Modified\\Abandoned-Removed\\TIC_littering\\" + name;

    VideoCapture vc1 = new VideoCapture(filename);
    VideoCapture vc2 = new VideoCapture(filename);

    int N = 100;

    for (int i = 0; i < N; i++){
        ok1 = vc1.read(m1);
        ok2 = vc2.read(m2);

        if (ok1 && ok2){
            Core.absdiff(m1, m2, m3);
            Imgproc.cvtColor(m3, m4, Imgproc.COLOR_BGR2GRAY);
            int differences = Core.countNonZero(m4);
            System.out.println("Total differences: " + differences);
        }           
        else System.out.println("Unable to load both frames");
    }
gaetano gravatar imagegaetano ( 2016-05-24 06:10:35 -0600 )edit

Here the output:

Total differences: 0 Total differences: 129845 Total differences: 129402 Total differences: 130983 ....

The output is indeed zero for the first frame, but then it is non zero on multiple occasions.

gaetano gravatar imagegaetano ( 2016-05-24 06:11:43 -0600 )edit

I don't know. The Java code should work fine like as mine in C++. Maybe is some OS and/or codec issue. Some other user who has a Java ready installation should test your code.

pklab gravatar imagepklab ( 2016-05-24 09:12:20 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-05-21 02:46:28 -0600

Seen: 1,914 times

Last updated: May 24 '16