2016-09-22 101 views
0

由於現在是我的學校假期,我決定選擇一些技巧,因此我試圖學習如何在Visual Studio C++中使用OpenCV功能來檢測許多罐在紙箱,並不得不將其分組4 4。 enter image description here使用Opencv和Hough變換圓圈來檢測圓圈(下標錯誤)

我已經嘗試了各種演示代碼,如「opencv find:contour」,模板匹配(無法正常工作,因爲它無法檢測到旋轉頂部蓋子)

我發現的最佳方法是將Canny邊緣檢測和Hough變換圓組合起來,使得Canny邊緣檢測的輸出結果可以是Hough變換圓的輸入圖像,結果如下。

enter image description here

不幸的是,當檢測到不是所有的圈子,如果我改變

for (int i = 0; i < circles.size(); i++)

for (int i = 0; i < 24; i++) // 24 is the no. of cans 

我會得到一個表達:向量下標超出範圍。我不知道爲什麼它是唯一能夠檢測21圈

來源如下代碼: -

using namespace cv; 
using namespace std; 
Mat src, src_gray; 

int main() 
{ 
Mat src1; 

src1 = imread("cans.jpg", CV_LOAD_IMAGE_COLOR); 
namedWindow("Original image", CV_WINDOW_AUTOSIZE); 
imshow("Original image", src1); 


Mat gray, edge, draw; 
cvtColor(src1, gray, CV_BGR2GRAY); 

Canny(gray, edge,50, 150, 3); 
//50,150,3 

edge.convertTo(draw, CV_8U); 
namedWindow("Canny Edge", CV_WINDOW_AUTOSIZE); 
imshow("Canny Edge", draw); 
imwrite("output.jpg", draw); 


waitKey(500); 




/// Read the image 
src = imread("output.jpg", 1); 
Size size(932, 558);//the dst image size,e.g.100x100 
resize(src, src, size);//resize image 

/// Convert it to gray 
cvtColor(src, src_gray, CV_BGR2GRAY); 

/// Reduce the noise so we avoid false circle detection 
GaussianBlur(src_gray, src_gray, Size(9, 9), 2, 2); 

vector<Vec3f> circles; 

/// Apply the Hough Transform to find the circles 
HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8,200, 100, 0, 0); 

/// Draw the circles detected 
for (int i = 0; i < circles.size(); i++) 
{ 
    printf("are you um?\n"); 
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); 
    int radius = cvRound(circles[i][2]); 
    // circle center 
    circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0); 
    // circle outline 
    circle(src, center, radius, Scalar(255, 0, 255), 3, 8, 0); 
} 

// namedWindow("Hough Circle Transform Demo", CV_WINDOW_NORMAL); 
    imshow("Hough Circle Transform Demo", src); 
    line(src, Point(0, 288), Point(1024, 288), Scalar(225, 220, 225), 2, 8); 
    // middle line 
    line(src, Point(360, 0), Point(360, 576), Scalar(225, 220, 225), 2, 8); 
    //break cans into 4 by 4 
    line(src, Point(600, 0), Point(600, 576), Scalar(225, 220, 225), 2, 8); 
          //  x, y 
    imshow("Lines", src); 
    imwrite("lineoutput.jpg", src); 


    waitKey(0); 


    return 0; 
} 

我還手工打出來的座標爲線,以它們分成4×4 enter image description here 爲了避免下標超出範圍並且能夠檢測到所有圈子,我應該更改哪些內容?

+0

你不能訪問超過你找到的東西。它創建了21個圓圈,所以矢量包含21個圓圈。如果將循環變量更改爲24,則會得到下標錯誤,導致向量大小爲21.您無法訪問其大小。要找到缺少的圈子,您可以添加程序中的圈子。它不會總是有效,但在某種程度上它會起作用。它像一個6x4的網格。從中心的距離,你可以很容易地假設哪些圈丟失..... –

+0

我不認爲我會手動添加圓圈,因爲我有10多個不同的照明和位置的圖像。 謝謝!修正了下標錯誤,我的6x4網格可能只是爲了顯示,因爲它什麼都不做:l – Lyber

回答

1

好吧解決了我自己的問題。將CV_BGR2GRAY更改爲CV_RGB2GRAY,使文件比率更小,更改圓圈半徑最小值並應用另一個閾值來獲取圓圈。 enter image description here

+0

嘗試不同的光線和其他條件......你不會總是有所有的圓圈。它可能會失敗:) –

+0

是的..我試着用不同的照明,但不幸的是我不能在不改變代碼的值的情況下得到所有的圓:c 有沒有什麼解決方案,我想知道? – Lyber

+0

功能匹配如Ransac和篩選? – Lyber