Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

OpenCV Buffer Overflow Issue...

I've got myself in a pickle on this project I'm working on. My main objective is to stitch two webcam feeds together and do object detection on them - bounding boxes, etc...the standard stuff.

I can't rid myself of buffer overflows though - the somewhat simplified code below (for readability) compiles x64 and soon after I get a buffer overflow error and this in the console:

OpenCV Error: Assertion Failed (contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S)) in unknown function, file ..\..\..\src\opencv\modules\imgproc\src\contours.cpp, line 1904

If comment out all of the lines that have to do with contours (from findContours to drawBoundingBoxes in main) it compiles and runs fine until I hit the spacebar to stop the program, and then I get another buffer overflow error. I get the same errors when I compile x32 as well, for the record.

Any help? Relevant code/pseudo-code pasted below:

// **defines.h**
//Definitions for anything in all caps, like WIDTH, HEIGHT, ERODEIT, etc...

// **protos.h**
// All function prototypes, nothing else

// **detection.cpp**

/* This is the code that related to background subtraction operations*/

#include <opencv2/opencv.hpp>
#include <iostream>
#include "defines.h"

using namespace std;
using namespace cv;

void initBackgroundSubtractor(BackgroundSubtractorMOG2 &bSub)
{
    bSub.set("detectShadows", 1);
}

Mat doBackgroundSubtract(BackgroundSubtractorMOG2 &bSub, Mat panorama)
{
    Mat foreground;

    bSub.operator()(panorama, foreground);
    erode(foreground, foreground, Mat(), Point(-1, -1), ERODEIT, BORDER_DEFAULT);
    dilate(foreground, foreground, Mat(), Point(-1, -1), DILATEIT, BORDER_DEFAULT);

    return foreground;
}

// **contourOps.cpp**

/* Functions that operate on, filter, or relate to OpenCV contours vectors */

#include <opencv2/opencv.hpp>
#include <vector>
#include <fstream>
#include "defines.h"

using namespace std;
using namespace cv;

/* Returns the centroid of a contour */

Point getCentroid(vector<Point> contour)
{
    Point centroid;
    Moments m;

    m = moments(contour, false);
    centroid.x = int(m.m10/m.m00);
    centroid.y = int(m.m01/m.m00);

    return centroid;
}

/* Draws a rectangle around a contour */

void drawBoundingBoxes(vector<vector<Point>> contours, Mat &img)
{
    vector<Rect> boundRect(contours.size());

    for(unsigned int j = 0; j < contours.size(); j++)
    {
        boundRect[j] = boundingRect(contours[j]);
        rectangle(img, boundRect[j], Scalar(153,0,76), 2, 8, 0);
    }
}

/* Removes contours from a vector if they're smaller than the argument "area" */

void contourSizeTrim (vector<vector<Point>> &contours, int area)
{
    vector<vector<Point>>::iterator i = contours.begin();
    while(i != contours.end())
    {
        if(contourArea(*i, false) < area)
            i = contours.erase(i);
        else
            i++;
    }
}

/* Removes contours from a vector if they're X % smaller than largest contour in vector */

void contourRelSizeTrim(vector<vector<Point>> &contours, int percent)
{
    double maxArea = 0.0;

    for(unsigned int i=0; i<contours.size(); i++)
    {
        if (contourArea(contours[i], false) > maxArea)
                maxArea = contourArea(contours[i], false);
    }

    vector<vector<Point>>::iterator j = contours.begin();
    while(j != contours.end())
    {
        if (contourArea(*j, false) < (double)(percent/100.0)*maxArea)
            j = contours.erase(j);
        else
            j++;
    }
}

// **realtimestitch.cpp**

#include <opencv2/opencv.hpp>
#include <opencv2/stitching/stitcher.hpp>
#include <vector>
#include <iostream>
#include "defines.h"

using namespace std;
using namespace cv;

void initStitcher(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
    capture1.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
    capture1.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
    capture2.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
    capture2.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);

    detail::OrbFeaturesFinder *featureFinder = new detail::OrbFeaturesFinder(Size(3,1), 1000, 1.5f, 4);
    stitch.setFeaturesFinder (featureFinder);
}

void calcCamTransform(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
    int64 t;
    Mat fr1, fr2, copy1, copy2;
    vector<Mat> imgs;

    capture1 >> fr1;
    capture2 >> fr2;
    fr1.copyTo(copy1);
    fr2.copyTo(copy2);
    imgs.push_back(copy1);
    imgs.push_back(copy2);
    stitch.estimateTransform(imgs);
}

Mat doStitch(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
    Mat fr1, fr2, copy1, copy2, panorama;
    vector<Mat> imgs;

    capture1 >> fr1;
    capture2 >> fr2;
    fr1.copyTo(copy1);
    fr2.copyTo(copy2);
    imgs.push_back(copy1);
    imgs.push_back(copy2);
    Stitcher::Status status = stitch.composePanorama(imgs, panorama);

    if (status != Stitcher::OK)
        cout << "Error Stitching: Code: " << int(status) << endl;

    return panorama;
}

// **main.cpp**

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include "defines.h"
#include "protos.h"

using namespace cv;

int main()
{
    bool doTransform = true, doSizeFilter = true, doRelSizeFilter = true;
    Mat pano, fGround;
    vector<vector<Point>> contours;
    VideoCapture cap1(0);
    VideoCapture cap2(1);
    Stitcher stitcher = Stitcher::createDefault();
    BackgroundSubtractorMOG2 bGround;

    initStitcher(cap1, cap2, stitcher);
    initBackgroundSubtractor(bGround);

    while (true)
    {
        if (doTransform)
        {
            calcCamTransform(cap1, cap2, stitcher);
            doTransform = !doTransform;
        }

        pano = doStitch(cap1, cap2, stitcher);
        fGround = doBackgroundSubtract(bGround, pano);


        findContours(fGround, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

        if (doSizeFilter)
            contourSizeTrim(contours, AREATHRESH);
        if (doRelSizeFilter)
            contourRelSizeTrim(contours, RELSIZEPERCENT);

        drawBoundingBoxes(contours, pano);

        imshow("Stitched Image", pano);

        if(waitKey(1) >= 0)
            break;
    }
    return 0;
}

Thanks!

OpenCV Buffer Overflow Issue...

I've got myself in a pickle on this project I'm working on. My main objective is to stitch two webcam feeds together and do object detection on them - bounding boxes, etc...the standard stuff.

I can't rid myself of buffer overflows though - the somewhat simplified code below (for readability) compiles x64 and soon after I get a buffer overflow error and this in the console:

OpenCV Error: Assertion Failed (contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S)) in unknown function, file ..\..\..\src\opencv\modules\imgproc\src\contours.cpp, line 1904

If comment out all of the lines that have to do with contours (from findContours to drawBoundingBoxes in main) it compiles and runs fine until I hit the spacebar to stop the program, and then I get another buffer overflow error. Instead, if I set doSizeFilter and doRelSizeFilter = false and leave those uncommented, and just comment out findContours(), it again runs okay until I hit spacebar. I get the same errors when I compile x32 as well, for the record.

Any help? Relevant code/pseudo-code pasted below:

// **defines.h**
//Definitions for anything in all caps, like WIDTH, HEIGHT, ERODEIT, etc...

// **protos.h**
// All function prototypes, nothing else

// **detection.cpp**

/* This is the code that related to background subtraction operations*/

#include <opencv2/opencv.hpp>
#include <iostream>
#include "defines.h"

using namespace std;
using namespace cv;

void initBackgroundSubtractor(BackgroundSubtractorMOG2 &bSub)
{
    bSub.set("detectShadows", 1);
}

Mat doBackgroundSubtract(BackgroundSubtractorMOG2 &bSub, Mat panorama)
{
    Mat foreground;

    bSub.operator()(panorama, foreground);
    erode(foreground, foreground, Mat(), Point(-1, -1), ERODEIT, BORDER_DEFAULT);
    dilate(foreground, foreground, Mat(), Point(-1, -1), DILATEIT, BORDER_DEFAULT);

    return foreground;
}

// **contourOps.cpp**

/* Functions that operate on, filter, or relate to OpenCV contours vectors */

#include <opencv2/opencv.hpp>
#include <vector>
#include <fstream>
#include "defines.h"

using namespace std;
using namespace cv;

/* Returns the centroid of a contour */

Point getCentroid(vector<Point> contour)
{
    Point centroid;
    Moments m;

    m = moments(contour, false);
    centroid.x = int(m.m10/m.m00);
    centroid.y = int(m.m01/m.m00);

    return centroid;
}

/* Draws a rectangle around a contour */

void drawBoundingBoxes(vector<vector<Point>> contours, Mat &img)
{
    vector<Rect> boundRect(contours.size());

    for(unsigned int j = 0; j < contours.size(); j++)
    {
        boundRect[j] = boundingRect(contours[j]);
        rectangle(img, boundRect[j], Scalar(153,0,76), 2, 8, 0);
    }
}

/* Removes contours from a vector if they're smaller than the argument "area" */

void contourSizeTrim (vector<vector<Point>> &contours, int area)
{
    vector<vector<Point>>::iterator i = contours.begin();
    while(i != contours.end())
    {
        if(contourArea(*i, false) < area)
            i = contours.erase(i);
        else
            i++;
    }
}

/* Removes contours from a vector if they're X % smaller than largest contour in vector */

void contourRelSizeTrim(vector<vector<Point>> &contours, int percent)
{
    double maxArea = 0.0;

    for(unsigned int i=0; i<contours.size(); i++)
    {
        if (contourArea(contours[i], false) > maxArea)
                maxArea = contourArea(contours[i], false);
    }

    vector<vector<Point>>::iterator j = contours.begin();
    while(j != contours.end())
    {
        if (contourArea(*j, false) < (double)(percent/100.0)*maxArea)
            j = contours.erase(j);
        else
            j++;
    }
}

// **realtimestitch.cpp**

#include <opencv2/opencv.hpp>
#include <opencv2/stitching/stitcher.hpp>
#include <vector>
#include <iostream>
#include "defines.h"

using namespace std;
using namespace cv;

void initStitcher(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
    capture1.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
    capture1.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
    capture2.set(CV_CAP_PROP_FRAME_WIDTH, WIDTH);
    capture2.set(CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);

    detail::OrbFeaturesFinder *featureFinder = new detail::OrbFeaturesFinder(Size(3,1), 1000, 1.5f, 4);
    stitch.setFeaturesFinder (featureFinder);
}

void calcCamTransform(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
    int64 t;
    Mat fr1, fr2, copy1, copy2;
    vector<Mat> imgs;

    capture1 >> fr1;
    capture2 >> fr2;
    fr1.copyTo(copy1);
    fr2.copyTo(copy2);
    imgs.push_back(copy1);
    imgs.push_back(copy2);
    stitch.estimateTransform(imgs);
}

Mat doStitch(VideoCapture &capture1, VideoCapture &capture2, Stitcher &stitch)
{
    Mat fr1, fr2, copy1, copy2, panorama;
    vector<Mat> imgs;

    capture1 >> fr1;
    capture2 >> fr2;
    fr1.copyTo(copy1);
    fr2.copyTo(copy2);
    imgs.push_back(copy1);
    imgs.push_back(copy2);
    Stitcher::Status status = stitch.composePanorama(imgs, panorama);

    if (status != Stitcher::OK)
        cout << "Error Stitching: Code: " << int(status) << endl;

    return panorama;
}

// **main.cpp**

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include "defines.h"
#include "protos.h"

using namespace cv;

int main()
{
    bool doTransform = true, doSizeFilter = true, doRelSizeFilter = true;
    Mat pano, fGround;
    vector<vector<Point>> contours;
    VideoCapture cap1(0);
    VideoCapture cap2(1);
    Stitcher stitcher = Stitcher::createDefault();
    BackgroundSubtractorMOG2 bGround;

    initStitcher(cap1, cap2, stitcher);
    initBackgroundSubtractor(bGround);

    while (true)
    {
        if (doTransform)
        {
            calcCamTransform(cap1, cap2, stitcher);
            doTransform = !doTransform;
        }

        pano = doStitch(cap1, cap2, stitcher);
        fGround = doBackgroundSubtract(bGround, pano);


        findContours(fGround, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

        if (doSizeFilter)
            contourSizeTrim(contours, AREATHRESH);
        if (doRelSizeFilter)
            contourRelSizeTrim(contours, RELSIZEPERCENT);

        drawBoundingBoxes(contours, pano);

        imshow("Stitched Image", pano);

        if(waitKey(1) >= 0)
            break;
    }
    return 0;
}

Thanks!