2015-09-11 5 views
1

Я пытаюсь использовать openCV для обнаружения красного круглого объекта и начертания круга вокруг этого объекта. Однако ошибка сегментации возникает, когда я использую функцию круга для рисования круга. Я не знаю, почему это происходит и как это исправить? Благодаря!!Как исправить ошибку сегментации OpenCV?

#include <opencv/cvaux.h> 
#include <opencv/highgui.h> 
#include <opencv/cxcore.h> 

#include <stdlib.h> 
#include <cv.hpp> 
#include <cxcore.hpp> 
#include <highgui.h> 
#include <opencv2/core/core.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 

#include<stdio.h> 
#include<math.h> 
#include<opencv/cv.h> 
#include<opencv/highgui.h> 
#include<opencv2/objdetect/objdetect.hpp> 
#include<opencv2/highgui/highgui.hpp> 
#include<opencv2/imgproc/imgproc.hpp> 
#include<vector> 

using namespace cv; // if you don want to use scope resolution operator(::) in the code to call the classes or functions from cv namespace, you need this line 
using namespace std; // if you don want to use scope resolution operator(::) in the code to call the classes or functions from std namespace, you need this line 


int main(int argc, char* argv[]){ 

VideoCapture capWebcam(0); //use scope resolution operator :: because VideoCapture is a class under namespace of cv 
           //use VideoCapture class to instantiate an object called capWebcam; here used the constructor of the object immediately to 
           //grab the only (0) camera 

if(capWebcam.isOpened()==false){ //check whether the camera is detected and successfully grabbed 


    printf("Error: camera not detected!!\n"); 
    cout<<"Error: camera not detected!!\n"<<endl; 
    return(1); 
} 


    Mat matOriginal; // matrix object used to store image from webcam 
    Mat matProcessed; 

    vector<Vec3f> vecCircles; //declare a 3-element vector of type floats, this will be the pass by reference(i.e. a pointer) output of HoughCicles() 

    vector<Vec3f>::iterator itrCircles; //iterator for circles vector just a counter, but has the same data type from the itrCircles' data member 

    namedWindow("Original"); //window for original image 
    namedWindow("Processed"); //window for Processed image 

    char charCheckForEscKey =0; 

    while(charCheckForEscKey!=27){ //as long as ESC is not pressed, stays in the while 

      if(capWebcam.read(matOriginal) == false){ //check to see whether the image read from webcam correctly 

        cout<<"Error: image frame not read!!\n"<<endl; 
       break; 
      } // 

    inRange(matOriginal,  //this time we don't need to pass a pointer; we pass the image as an object instead 
      Scalar(0,0,175), //specify the lower bound of BGR we want to keep 
      Scalar(100,100,256), //upper bound of BGR 
      matProcessed); //return the processed image to another object 


    GaussianBlur(matProcessed,matProcessed,Size(9,9),1.5,1.5); //take matProcessed image and blur by Gaussian filter(9x9 window with std of 1.5 in both x,y direction) and return to same object 

    HoughCircles(matProcessed, 
       vecCircles, //use vector element to receive the x,y,radius of the detected circle 
       CV_HOUGH_GRADIENT, //algorithms used to detect circles 
       2,     //size of image divided by this value = "accumulator resolution" 
       matProcessed.rows/4, //min distance between the centers of two detected circles 
       100,  //upper pixel value threshold for canny edge detection to interpret as edge 
       50,  //lower pixel value threshold for canny edge detection to interpret as edge 
       10,  //min radius of a circle can be detected 
       400);  //max radius of a circle can be detected 

    for(itrCircles = vecCircles.begin();itrCircles != vecCircles.end();itrCircles++) //retrieve the x,y and radius of the detected circles from vecCircles object one by one 


     cout<< "circle position x = " << (*itrCircles)[0] //because itrCircles is a pointer(pass by reference), to get the value need to use * to dereference 
          << ",y = " << (*itrCircles)[1] 
          << ",r = " << (*itrCircles)[2] << "\n" << endl; 


     // draw the center of detected circle in green 
     circle(matOriginal, 
       Point((int)(*itrCircles)[0],(int)(*itrCircles)[1]), 
       3, 
       Scalar(0,255,0), 
       CV_FILLED); 


     // draw the circumference of detected circle 
     circle(matOriginal, 
       Point((int)(*itrCircles)[0],(int)(*itrCircles)[1]), 
       (int)(*itrCircles)[2], 
       Scalar(0,0,255), 
       3); 


    imshow("Original",matOriginal); //show the original mat(image) in Original window 
    imshow("Processed",matProcessed);// show the processed mat(image) in Processed window 

    charCheckForEscKey = waitKey(10); // delay 10 ms to allow a time gap to listen to any key pressed 

} // end while 


return(0); 
} // end main 
+2

Вы начинаете с запуска в отладчике, чтобы найти сбой в коде. Когда вы запустите в отладчике, отладчик остановится, когда произойдет сбой, и вы можете изучить и подобрать стек вызовов функций, а также изучить значения переменных. Если отладчик не останавливается в вашем коде, поднимите стек вызовов до тех пор, пока вы не достигнете своего кода, и проверьте переменные, участвующие в выражении, вызывающем сбой. По крайней мере, пожалуйста, сузите код в своем вопросе к проблематичной части и сообщите нам, где произошел сбой, и переменные значения. –

+0

Вы компилировались в режиме отладки и ссылались на библиотеки выпуска или наоборот? – Micka

+0

Спасибо за ваши предложения! Я новичок в OpenCV. Я использовал режим отладки, и он показывает, что ошибка возникает в функции 1-го круга, когда я хочу нарисовать центр обнаруженных кругов. Спасибо, что Мики исправил мою ошибку. –

ответ

0

Катастрофа вызвана отсутствующей скобкой на для цикла, и поэтому итераторы вы используете, чтобы сделать не правильно инициализирован. Вы должны сделать:

for(itrCircles = vecCircles.begin();itrCircles != vecCircles.end();itrCircles++) 
{ 
    // your functions 
} 

Могу ли я предложить отказаться от итераторов и использовать цикл foreach?

for (const auto& circ : vecCircles) 
{ 
    // your functions 
} 

Здесь полный пример, очищенный от всех бесполезных предметов (особенно бесполезных заголовков).

#include <opencv2\opencv.hpp> 
#include <iostream> 
#include<vector> 

using namespace cv; 
using namespace std; 

int main(){ 

    VideoCapture capWebcam(0); 
    if (capWebcam.isOpened() == false){ 
     cout << "Error: camera not detected!!\n" << endl; 
     return -1; 
    } 

    Mat matOriginal; // matrix object used to store image from webcam 
    Mat matProcessed; 
    vector<Vec3f> vecCircles; 

    namedWindow("Original"); //window for original image 
    namedWindow("Processed"); //window for Processed image 

    char charCheckForEscKey = 0; 
    while (charCheckForEscKey != 27){ //as long as ESC is not pressed, stays in the while 

     if (!capWebcam.read(matOriginal)){ 
      cout << "Error: image frame not read!!" << endl; 
      break; 
     } // 

     inRange(matOriginal,  //this time we don't need to pass a pointer; we pass the image as an object instead 
      Scalar(0, 0, 175), //specify the lower bound of BGR we want to keep 
      Scalar(100, 100, 256), //upper bound of BGR 
      matProcessed); //return the processed image to another object 

     GaussianBlur(matProcessed, matProcessed, Size(9, 9), 1.5, 1.5); //take matProcessed image and blur by Gaussian filter(9x9 window with std of 1.5 in both x,y direction) and return to same object 

     HoughCircles(matProcessed, 
      vecCircles, //use vector element to receive the x,y,radius of the detected circle 
      CV_HOUGH_GRADIENT, //algorithms used to detect circles 
      2,     //size of image divided by this value = "accumulator resolution" 
      matProcessed.rows/4, //min distance between the centers of two detected circles 
      100,  //upper pixel value threshold for canny edge detection to interpret as edge 
      50,  //lower pixel value threshold for canny edge detection to interpret as edge 
      10,  //min radius of a circle can be detected 
      400);  //max radius of a circle can be detected 

     for (const auto& circ : vecCircles) //retrieve the x,y and radius of the detected circles from vecCircles object one by one 
     { 
      cout << "circle position x = " << circ[0] //because itrCircles is a pointer(pass by reference), to get the value need to use * to dereference 
       << ",y = " << circ[1] 
       << ",r = " << circ[2] << "\n" << endl; 

      // draw the center of detected circle in green 
      circle(matOriginal, Point(circ[0], circ[1]), 3, Scalar(0, 255, 0), CV_FILLED); 

      // draw the circumference of detected circle 
      circle(matOriginal, Point(circ[0], circ[1]), circ[2], Scalar(0, 0, 255), 3); 
     } 

     imshow("Original", matOriginal); //show the original mat(image) in Original window 
     imshow("Processed", matProcessed);// show the processed mat(image) in Processed window 

     charCheckForEscKey = waitKey(10); // delay 10 ms to allow a time gap to listen to any key pressed 

    } // end while 

    return(0); 
} // end main 
+0

Большое спасибо! Я новичок в OpenCV. –

Смежные вопросы