Переполнение буфера в OpenCV

Я оказался в центре внимания этого проекта, над которым я работаю. Моя главная цель — соединить два канала веб-камеры и обнаружить на них объекты — ограничивающие рамки и т. Д. — стандартные вещи.

Я не могу избавиться от переполнения буфера, хотя несколько упрощенный код ниже (для удобства чтения) компилирует x64, и вскоре после этого я получаю ошибку переполнения буфера, и это в консоли:

"OpenCV Error: Assertion Failed (contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || CV_32S) in unknown function, file...."

Если закомментировать все линии, которые имеют отношение к контурам (из findContours в drawBoundingBoxes в основном) он компилируется и работает нормально, пока я не нажму пробел, чтобы остановить программу, а затем я получу еще одну ошибку переполнения буфера. Я получаю те же ошибки при компиляции x32, для записи.

Любая помощь? Соответствующий код / ​​псевдокод, вставленный ниже:

// **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;
}

0

Решение

Это проблема, связанная с OpenCV и VS2012 — на VS2010 проблем нет, и код работает отлично!

0

Другие решения

Мое мнение по этому поводу таково, что по контуру вы пытаетесь что-то сделать с пустым вектором контуров. Вы это подтвердили? Попробуйте

if (contours.empty()) continue; // or here you can display the image to see if it is empty or not

У меня была такая же проблема, потому что я пытался дать эпты вектор cv::IsContourConvex(...) функция (посмотреть здесь).

0