4

我正在進行硬幣識別項目。 我被卡住的第一件事是從圖像中提取正確的硬幣,即使是從非常簡單的圖像。 硬幣檢測存在很多好的工作方法,但所有這些方法在我看來都需要在應用後進行人工檢查。我測試了其中兩個:OpenCV硬幣檢測和自動結果檢查

cv2.HoughCircles和閾值findig countours之後。

這裏處理的一些全成例子:

cv2.HoughCircles,好的結果

enter image description here

cv2.HoughCircles,壞的結果

enter image description here

但對於第二個形象工程發現countours後threshloding的偉大的解決方案和:

是這樣的:

gray = cv2.GaussianBlur(gray, (15, 15), 0) 

#gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV, 11, 1) 
    (_,gray) = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) 
    contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 

for i,cnt in enumerate(contours): 
    ellipse = cv2.fitEllipse(cnt) 
    print ellipse,type(ellipse) 
    cv2.ellipse(color_img, ellipse, (0,255,0), 2) 

產生了很好的效果:

enter image description here

但對於其他一些它的作品非常純淨,

enter image description here

發生這種情況是因爲硬幣要從另一個關閉一個,bluring已合併它們。這是非常簡單的CAS,因爲我可以檢查結果是否只有一個輪廓下降。但有時它更復雜。我想實現一些算法,嘗試不同的細分方法並選擇最好的方法。但很難爲我編碼這個指標 - 有任何人想法如何做到這一點?從例如

原始圖片:這 3是相當qute,但實際上是不規律 - 他們中的一些有背景他們中的一些甚至沒有硬幣 - 這就是爲什麼我想一些postchecking過程。

enter coin1

enter coin2

enter coin3

enter coin4

enter image description here

+0

你的意思是這樣(不包括大津有些下降最大脫粒值) cv2.threshold(灰色,0250,cv2.THRESH_BINARY_INV) – Oleg

+0

cv2.threshold(灰色,160,255,cv2.THRESH_BINARY_INV) 作品對於這種情況,但僅限於這一個 – Oleg

+0

總是隻有一個coint(2個邊)在圖像上?如果您能夠使用該信息來準確找到2個(幾乎相同大小)的輪廓,則該任務應該非常容易解決。 – Micka

回答

2

我使用斑點檢測器使用以下參數獲得了成功:

Ptr<SimpleBlobDetector> detector; 
SimpleBlobDetector::Params params; 
params.minThreshold = 150; 
params.maxThreshold = 230; 
params.filterByArea = true; 
params.minArea = 50; 
params.maxArea = 50000; 
params.filterByConvexity = true; 
params.minConvexity = 0.9; 
params.maxConvexity = 1.0; 

params.filterByCircularity = false; 
params.filterByInertia = false; 
params.filterByColor = false; 
detector = SimpleBlobDetector::create(params); 

然後找到斑點和繪製圓圈:

Mat SearchImage; // set to whatever picture contains coins 
Mat DrawImage; // image to draw on with drawKeypoints 
SearchImage.copyTo(DrawImage); 
vector<cv::KeyPoint> keypoints; 
detector->detect(SearchImage, keypoints); 
drawKeypoints(SearchImage, keypoints, DrawImage, Scalar(0, 0, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); 

編輯: 此示例代碼是在C++中。有關示例,請參閱here

+0

感謝BlobDetector我喜歡這種方法。但問題是無論如何存在。在某些情況下,它有些不起作用。我必須對閾值參數進行微調以獲得正確答案。實際上 - minThreshold上的brutferoce並不是一個壞主意,但它不清楚如何檢查算法的結果 - 什麼是好的答案,什麼是壞的。沒有關鍵點是不好的。但是一個關鍵點也可能是不好的答案(就像在第三個例子中那樣),但可能不是。 – Oleg