我正在开发一个使用OpenCV进行圆圈检测的软件。我认为最重要的问题是形象。以前我尝试通过HoughCircles
检测圈子,结果不好。之后,我尝试按照this post中的说明操作,但它不起作用。也许我需要一些帮助来预处理图像。有没有人有任何其他想法来检测边缘?
原始图片:
其他类似图片: http://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);
}