Saya sedang mengerjakan perangkat lunak menggunakan OpenCV untuk deteksi lingkaran. Menurut saya, masalah yang paling penting adalah gambar. Sebelumnya saya mencoba mendeteksi lingkaran sebesar HoughCircles
dengan hasil yang buruk. Setelah itu, saya mencoba mengikuti petunjuk di postingan ini tetapi tidak berhasil. Mungkin saya memerlukan bantuan untuk melakukan pra-pemrosesan gambar. Adakah yang punya ide lain untuk mendeteksi tepian?
Gambar asli :
gambar serupa lainnya: https://imgur.com/a/eSKFr
Di bawah ini saya telah memposting kode:
//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);
}