กล่องขอบเขตการตรวจจับวงกลม OpenCV

ฉันกำลังทำงานกับซอฟต์แวร์ที่ใช้ OpenCV สำหรับการตรวจจับแวดวง ฉันคิดว่าปัญหาที่สำคัญที่สุดคือภาพ ก่อนหน้านี้ฉันพยายามตรวจจับวงกลมด้วย HoughCircles ซึ่งได้ผลลัพธ์ที่ไม่ดี หลังจากนั้น ฉันพยายามทำตามคำแนะนำในโพสต์นี้ แต่มันไม่ทำงาน บางทีฉันอาจต้องการความช่วยเหลือในการประมวลผลภาพล่วงหน้า ใครมีแนวคิดอื่นในการตรวจจับขอบบ้าง

รูปภาพต้นฉบับ :

ป้อนคำอธิบายรูปภาพที่นี่

รูปภาพอื่นๆ ที่คล้ายกัน: https://imgur.com/a/eSKFr

ด้านล่างฉันได้โพสต์รหัส:

//Global variables
Mat src; Mat src_gray, threshold_output, element,dilated,eroded1, eroded2;
int thresh = 125;
int const max_value = 255;
int const max_BINARY_value = 255;
RNG rng(12345);
int s_ero1 =1;
int s_dil = 2;
int s_ero2 = 1;
int max_s = 50;
string source_window = "Thresh";
string TrackbarName = "Dilated";
string TrackbarName1 = "Eroded1";
string TrackbarName2 = "Eroded2";
/// Function header
void thresh_callback(int, void* );
void dilate_trackbar(int, void*);
void erode_trackbar1(int,void*);
void erode_trackbar2(int,void*);

int main( int, char** argv )
{
    /// Load source image and convert it to gray
    src = imread( "/media/Dati/image01.tif", 1 );


    /// Convert image to gray and blur it
    cvtColor( src, src_gray, COLOR_BGR2GRAY );
    blur( src_gray, src_gray, Size(3,3) );




    /// Create Window

    namedWindow( "source", WINDOW_NORMAL );
    imshow( "source", src );
    waitKey();

    namedWindow( source_window, WINDOW_NORMAL );
    //Create trackbar threshold
    createTrackbar( " Threshold:", source_window, &thresh, max_value, thresh_callback );
    thresh_callback( 0, 0 );
    waitKey();

    namedWindow( TrackbarName1, WINDOW_NORMAL );
    createTrackbar( "Size: ",  TrackbarName1, &s_ero1, max_s, erode_trackbar1);
    erode_trackbar1(0,0);
    waitKey();


    namedWindow( TrackbarName, WINDOW_NORMAL );
    createTrackbar( "Size: ",  TrackbarName, &s_dil, max_s, dilate_trackbar);
    dilate_trackbar(0,0);
    waitKey();

    namedWindow( TrackbarName2, WINDOW_NORMAL );
    createTrackbar( "Size: ",  TrackbarName2, &s_ero2, max_s, erode_trackbar2);
    erode_trackbar2(0,0);
    waitKey();



    return(0);
}


/**
* @function bounding_box
*/
void bounding_box(Mat m){
    int max_point_pos = 0;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    // Find contours
    findContours( m, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0) );

    cout<<"Numero di blob: "<< contours.size()<<endl;
    for(int i = 1; i < contours.size(); i++){
             max_point_pos = contours[max_point_pos].size() > contours[i].size()? max_point_pos  : i;

    }

    int max_point = contours[max_point_pos].size();
    cout<< "il blob con più punti è associato alla posizione : " << max_point_pos << " con " << max_point << " punti"<< endl;

    /// Approximate contours to polygons + get bounding rects and circles
    vector<vector<Point> > contours_poly( contours.size() );
    vector<Rect> boundRect( contours.size() );
    vector<Point2f>center( contours.size() );
    vector<float>radius( contours.size() );

    for( int i = 0; i < contours.size(); i++ )
     { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
       boundRect[i] = boundingRect( Mat(contours_poly[i]) );
       minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
     }


    /// Draw polygonal contour + bounding rects + circles
    Mat drawing = src.clone();
    for( size_t i = 0; i< contours.size(); i++ )
     {
        if(contours[i].size() > 0.6*max_point){
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
       //drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
       //rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
       circle( drawing, center[i], (int)radius[i], color, 7, 8, 0 );
        }
     }

    /// Show in a window
    namedWindow( "Contours", WINDOW_NORMAL );
    imshow( "Contours", drawing );

}



/**
* @function thresh_callback
*/
void thresh_callback(int, void* )
{


    /// Detect edges using Threshold
    threshold( src_gray, threshold_output, thresh, max_BINARY_value, THRESH_BINARY_INV);
    imshow(source_window, threshold_output);

}


/**
* @function dilate_trackbar
* @brief Callback for trackbar
*/
void dilate_trackbar( int, void* )
{
    dilated = threshold_output.clone();
    element = getStructuringElement(MORPH_ELLIPSE,Size(s_dil, s_dil) , Point(-1,-1));
    dilate(dilated,dilated,element,Point(-1,-1),1);
    imshow(TrackbarName, dilated);
}

/**
* @function erode_trackbar
* @brief Callback for trackbar
*/
void erode_trackbar1( int, void*)
{
    eroded1 = threshold_output.clone();
    element = getStructuringElement(MORPH_ELLIPSE,Size(s_ero1, s_ero1) , Point(-1,-1));
    erode(eroded1,eroded1,element,Point(-1,-1),1);
    imshow(TrackbarName1, eroded1);

}

person C. Ro    schedule 07.12.2015    source แหล่งที่มา
comment
คำถามของคุณคืออะไร?   -  person dfrib    schedule 07.12.2015
comment
วัตถุเหล่านั้นอยู่ใต้น้ำใช่ไหม? คุณสามารถเข้าถึงภาพหลายภาพจากตำแหน่งกล้องคงที่ (เช่น วิดีโอ) ได้หรือไม่?   -  person Micka    schedule 07.12.2015
comment
@dfri มีแนวคิดอื่นใดในการตรวจจับขอบหรือไม่   -  person C. Ro    schedule 07.12.2015
comment
@Micka น่าเสียดายที่ข้อมูลเดียวของฉันคือรูปภาพ ฉันไม่รู้ว่าวัตถุเหล่านั้นอยู่ใต้น้ำหรือไม่ ฉันไม่สามารถเข้าถึงภาพหลายภาพจากตำแหน่งกล้องคงที่ได้   -  person C. Ro    schedule 07.12.2015
comment
@C.Ro ขออภัยฉันไม่ได้ตั้งใจจะฟังดูคม แต่เป็นการดีเสมอที่จะระบุสิ่งที่คุณต้องการบรรลุโดยเฉพาะกับคำถามของคุณที่ SO การเพิ่มบางอย่างตามบรรทัด ใครมีแนวคิดอื่นในการตรวจจับขอบหรือไม่ ก่อนที่ภาพของคุณจะเหมาะสมที่จะแก้ไขในโพสต์ของคุณ   -  person dfrib    schedule 07.12.2015
comment
@dfri ฉันแย่คุณพูดถูก ฉันแก้ไขโพสต์   -  person C. Ro    schedule 07.12.2015
comment
ดังนั้นหากเป็นเพียงการตรวจจับวงกลมในภาพเดียวนั้น ฉันจะดำเนินการด้วยตนเอง... โปรดโพสต์ภาพที่สองของฉากอื่นเพื่อให้เข้าใจเนื้อหาได้ดีขึ้น   -  person Micka    schedule 07.12.2015
comment
@Micka ฉันต้องตรวจจับวงกลมด้วย OpenCV   -  person C. Ro    schedule 07.12.2015
comment
คุณมีภาพเพิ่มเติมของฉากต่าง ๆ ที่คุณรู้สึกถึงเนื้อหานั้นหรือไม่?   -  person Micka    schedule 07.12.2015
comment
@Micka ฉันได้อัปโหลดภาพเพิ่มเติมแล้ว ขอบคุณสำหรับความช่วยเหลือ   -  person C. Ro    schedule 07.12.2015
comment
การพึ่งพาความเร็วใด ๆ ? บางทีคุณอาจสามารถปรับการตรวจจับวงกลมโดยใช้การไล่ระดับสีทิศทางที่แตกต่างกันจำนวนมาก   -  person Micka    schedule 07.12.2015
comment
@Micka ไม่ ฉันมีเพียงภาพนี้เท่านั้น   -  person C. Ro    schedule 07.12.2015
comment
คุณจำเป็นต้องจำแนก 'วงกลมที่อยู่ในรูปภาพ' หรือไม่? - หรือค้นหาศูนย์กลางวงกลมจริง ๆ ? หากเป็นกรณีการจำแนกประเภทแบบง่าย ฉันขอแนะนำให้ฝึกอบรมเครื่องแยกประเภทการเรียนรู้ของเครื่องจักรบางประเภท...   -  person Lamar Latrell    schedule 08.12.2015
comment
@LamarLatrell คุณหมายถึงอะไรอย่างแน่นอนเมื่อคุณพูดถึงการจำแนกแวดวง?   -  person C. Ro    schedule 08.12.2015
comment
@C.Ro พูดอย่างเคร่งครัดว่าฉันไม่เคยพูดว่าจำแนกแวดวง ... ฉันจะลองถามมันด้วยวิธีอื่น: คุณต้องการฟังก์ชัน findCircles แบบนี้: bool CirclesPresent findCircles(Mat image){} หรือไม่? หรือเช่นนี้: vector‹Point2d› วงกลมพิกัด findCircles(Mat image{} ?   -  person Lamar Latrell    schedule 12.12.2015