2013-06-05 3 views
0

У меня есть рассол в этом проекте, над которым я работаю. Моя основная цель - сшить два веб-камеры вместе и сделать обнаружение объектов на них - ограничивающие поля и т. Д. - стандартное.Переполнение буфера 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

Можете ли вы отметить в коде код functino, вызывающий ошибку? Глядя на ваш код, я подозреваю, что проблема в том, что изображение fGroung, возвращаемое из фонового вычитателя, не является 8-битным 1-канальным изображением. http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours Итак, сначала проверьте тип fGrounf и при необходимости выполните некоторое преобразование порога или типа. – jnovacho

+0

В моем оригинальном посте я отмечаю хотя бы часть ошибки - это где-то в main.cpp между findContours и drawBoundingBoxes. Я попытался добавить строку: foreground.converTo (foreground, CV_8UC1) в функции doBackgroundSubtract() в detect.cpp безрезультатно. – TonyRo

+0

Итак, сначала попробуйте найти точную строку, вызывающую ошибку. Не зная, какая строка вызывает проблему, мы можем только догадываться. – jnovacho

ответ

0

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

0

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

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

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