Ask Your Question

AndreasM's profile - activity

2019-09-18 09:00:40 -0600 asked a question Why is max not equal to beta after using normalize?

Why is max not equal to beta after using normalize? I'm doing a simple template matching on an RGB image with an RGB tem

2014-07-10 19:41:07 -0600 asked a question VideoCapture returns empty frames on Windows after a while

I have a program which loads a video and does all sorts of stuff, irrelevant to this question. I use Ubuntu Linux, where it works without issue. Now I need it to run on Windows. When I compile and run it, at first it works fine. But at some point, VideoCapture starts returning empty frames. It differs from video to video exactly when it happens, usually around 13000-15000 frames into the video. The stopping point is the same every time I run the program on the same video, so at least it is deterministic.

I have created a very simple program in which the problem also happens:

#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
    bool loopFlag = true;
    int frameCounter = 0;


    VideoCapture cap("E:\\workFolder\\ed_1024.avi");
    if(!cap.isOpened()) {
        cout << "Could not open video.\n";
        return -1;
    }

    namedWindow("Capture", 1);
    Mat frame;

    while(loopFlag)
    {
        cap >> frame;
        if(frame.empty()) {
            cout << "Frame " << frameCounter << " is empty!";
            loopFlag = false;
            break;
        }
        imshow("Capture", frame);
        cout << "Showed frame " << frameCounter << endl;
        frameCounter++;
    }
    waitKey(0);
    return 0;
}

That is as barebones as I can do. When I run it with some of the videos I have captured, as mentioned it stops after several thousand frames. To verify that it is not my videos that are the problem, I downloaded the Open Source animation movie Elephants Dream in DivX (my own videos are Xvid). When I run the program with this, it stops after 74 frames:

Showed frame 0
Showed frame 1
[...]
Showed frame 73
Frame 74 is empty!

I'm considering if it is somehow a codec problem, but it does read the first frames just fine. I have Xvid and FFDShow installed on the Windows machine.

Any ideas? I hardly know where to begin the debugging.

2014-03-13 13:40:40 -0600 received badge  Supporter (source)
2013-02-22 05:54:13 -0600 received badge  Editor (source)
2013-02-22 05:52:08 -0600 answered a question OpenCV Draw draw contours of 2 largest objects

A simple approach could be to judge the size by the number of points in the contour and simply remove all contours which are not one of the two biggest. Something like this (right after findContours):

// Before all this you must #include <algorithm> to have access to min_element() and max_element()

int contourIds[] = {0, 1}; // Holds the indexes of the two largest contours.
int contourSizes[] = {contours[0].size(), contours[1].size()}; // Holds the values of the two largest contours.
for(int i = 2; i < (int)contours.size(); i++) { // Find the largest contours, start scanning at contour 2, since 0 and 1 are out initial assumptions for the largest.
    int smallest = *std::min_element(contourSizes, contourSizes+2);
    if(contours[i].size() <= smallest) {
        continue; // This contour is smaller than the two stored contours, so we ignore it.
    }
    // Replace the smallest:
    int smallestId = contourSizes[0] != smallest; // Find if the smallest is contained in spot 0 or 1 in contourIds and contourSizes (using that false == 0 and true == 1)
    contourIds[smallestId] = i;
    contourSizes[smallestId] = contours[i].size();
}
// Erase the 3 intervals of smaller contours:
contours.erase(contours.begin(), contours.begin()+*std::min_element(contourIds, contourIds+2));
contours.erase(contours.begin()+*std::min_element(contourIds, contourIds+2)+1, contours.begin()+*std::max_element(contourIds, contourIds+2));
contours.erase(contours.begin()+*std::max_element(contourIds, contourIds+2)+1, contours.end());

I have not tested the above code, but I think it should more or less work.

If you want to use the actual areas you can calculate the area of the contours with contourArea and store the actual area instead of the vector size in contourSizes. The code above should still work in that case.