2016-05-03 88 views
3

私は画像内の円を検出するためにPython用のOpenCVライブラリを使用しています。画像を表示し、その後、私は検出前の画像を表示すべき次のコードを、書いたOpenCVで重複する円を検出する

enter image description here

:缶の

下:テストケースとして、私は以下の画像を使用しています検出された円を追加しました:

import cv2 
import numpy as np 

image = cv2.imread('can.png') 
image_rgb = image.copy() 
image_copy = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 
grayscaled_image = cv2.cvtColor(image_copy, cv2.COLOR_GRAY2BGR) 

cv2.imshow("confirm", grayscaled_image) 
cv2.waitKey(0) 

cv2.destroyAllWindows() 


circles = cv2.HoughCircles(image_copy, cv2.HOUGH_GRADIENT, 1.3, 20, param1=60, param2=33, minRadius=10,maxRadius=28) 


if circles is not None: 
    print("FOUND CIRCLES") 
    circles = np.round(circles[0, :]).astype("int") 
    print(circles) 
    for (x, y, r) in circles: 
     cv2.circle(image, (x, y), r, (255, 0, 0), 4) 
     cv2.rectangle(image, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1) 
    cv2.imshow("Test", image + image_rgb) 
    cv2.waitKey(0) 

cv2.destroyAllWindows() 

が、私はこの取得:結果の画像を

enter image description here

私の問題はHoughCircles()機能の使用にあると感じます。 minDistは互いから一定の距離であることが検出された円を必要と0より大きい値である

cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])

:それは使用があるのです。この要件では、各円の中心が同じ場所にあるので、缶の底にあるすべての円を適切に検出することは不可能です。等高線は解決策ですか?どのように輪郭を円に変換して、中心点の座標を使用することができますか?缶の底にある各リングのサークルオブジェクトを最もよく検出するにはどうすればよいですか?

+0

ない問題の一部が、将来のために: 'image_copy = cv2.cvtColor(画像、cv2.COLOR_RGB2GRAY) '' image_copy = cv2.cvtColor(image、cv2.COLOR_BGR2GRAY) 'でなければなりません。 – Micka

答えて

1

は全てが、円の大部分は輪郭を見つけ、次に閾値

import cv2 
import numpy as np 

block_size,constant_c ,min_cnt_area = 9,1,400 
img = cv2.imread('viMmP.png') 
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
thresh = cv2.adaptiveThreshold(img_gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,block_size,constant_c) 
thresh_copy = thresh.copy() 
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
for cnt in contours: 
    if cv2.contourArea(cnt)>min_cnt_area: 
     (x,y),radius = cv2.minEnclosingCircle(cnt) 
     center = (int(x),int(y)) 
     radius = int(radius) 
     cv2.circle(img,center,radius,(255,0,0),1) 
cv2.imshow("Thresholded Image",thresh_copy) 
cv2.imshow("Image with circles",img) 
cv2.waitKey(0) 

このスクリプト収率よりも大きな面積を有する輪郭の最小外接円を当てはめ、適応的閾値によって画像を検出することができません結果:

enter image description here

enter image description here

しかしTHER block_sizeconstant_cがそれぞれ11および2に変更された場合に電子そして、のようなスクリプト利回り一定のトレードオフです:

enter image description here

enter image description here

あなたは、適切な形状のカーネルと浸食を適用してみてください閾値付き画像内の重なり合う円を分離する

適応閾値と等高線の詳細については、

を参照してください。の

Threshlding例:http://docs.opencv.org/3.1.0/d7/d4d/tutorial_py_thresholding.html

しきい参照:http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html

輪郭例:

http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html
+0

もし私が各リングの正確なサイズを完全に検出できないならば、イメージ全体を検出する方法はありますか?言っておいて、私がウェブカメラを使って缶の画像を掲げたら、プログラムはその画像を特に検出するでしょうか? – user5705019

+0

はい、画像をHSVに変換して、適切なしきい値で画像をしきい値処理することができます。しきい値処理された画像にクロージング操作(エロージョン+膨張)を適用して、背景に起因する不要なノイズ成分を除去します。次に、RETR_EXTERNALを使用してこのマスクの外部輪郭を探します。イメージにノイズの多いコンポーネントがない場合は、外側のサークルを取得します。再び輪郭領域を使用してノイズの多いコンポーネントをすべて削除することができます。黒い背景に缶を入れたい場合はビット単位で、マスクは元のBGR画像で閉じた後に得られます。 –

+0

私は本当に応答を感謝しますが、私はどのようにそれを行うか分からない。私はOpenCVの新人です。私はOpenCVの使い方に関する質の高いガイドを見つけることができません。何かお勧めしますか?どうやってそれを学びましたか? – user5705019

関連する問題