2017-02-13 16 views
8

मुझे सर्कल क्षेत्रों का पता लगाने में समस्याएं आ रही हैं। मैंने इसे opencv से HoughCircles फ़ंक्शन के साथ करने की कोशिश की। हालांकि भले ही छवियां बहुत समान हैं, मूर्तियों के पता लगाने के लिए मज़े के लिए पैरामीटर अलग-अलग होना चाहिए।पायथन ओपनसीवी - ब्लोब डिटेक्शन या सर्कल डिटेक्शन

मैंने कोशिश की एक और दृष्टिकोण हर पिक्सेल पर फिर से शुरू करना था और जांचें कि वर्तमान पिक्सेल सफेद है या नहीं। यदि यह मामला है तो जांच करें कि क्षेत्र में ब्लॉब ऑब्जेक्ट है (थ्रेसहोल्ड से छोटे ब्लॉब सेंटर की दूरी)। यदि वहां है, तो पिक्सेल को ब्लॉब में संलग्न करें, यदि नहीं तो एक नया ब्लॉब बनाएं। यह भी ठीक से काम नहीं किया।

क्या किसी को यह पता है कि मैं यह काम कैसे कर सकता हूं (9 0% पहचान)? मैंने एक उदाहरण छवि और एक और छवि संलग्न की जहां मैंने cirles चिह्नित किया। धन्यवाद!

example

example with arrows

अद्यतन: अब तक मदद के लिए धन्यवाद! इस कोड को जहाँ मैं आकृति को प्राप्त करने और क्षेत्र के हिसाब से उन्हें फ़िल्टर है:

im = cv2.imread('extract_blue.jpg') 
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) 
im_gauss = cv2.GaussianBlur(imgray, (5, 5), 0) 
ret, thresh = cv2.threshold(im_gauss, 127, 255, 0) 
# get contours 
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 

contours_area = [] 
# calculate area and filter into new array 
for con in contours: 
    area = cv2.contourArea(con) 
    if 1000 < area < 10000: 
     contours_area.append(con) 

यह सुंदर स्वच्छ काम करता है। मैं उन्हें छवि पर आकर्षित किया:

contours_cirles = [] 

# check if contour is of circular shape 
for con in contours_area: 
    perimeter = cv2.arcLength(con, True) 
    area = cv2.contourArea(con) 
    if perimeter == 0: 
     break 
    circularity = 4*math.pi*(area/perimeter*perimeter) 
    print circularity 
    if 0.8 < circularity < 1.2: 
     contours_cirles.append(con) 

हालांकि, नई सूची 'contours_cirles': contours_filtered_area

यह हिस्सा है जहाँ मैं घेरा द्वारा फ़िल्टर है, यह सीधे कोड, जहां मैं क्षेत्र के आधार पर फ़िल्टर नीचे चला जाता है खाली है। मैं पाश में 'घेरा' मुद्रित और मूल्यों सब के बीच 10 000 और 100 000.

अद्यतन # 2 हैं: लापता कोष्ठक यह अब काम कर रहा है ठीक करने के बाद !

contours_cirles = [] 

# check if contour is of circular shape 
for con in contours_area: 
    perimeter = cv2.arcLength(con, True) 
    area = cv2.contourArea(con) 
    if perimeter == 0: 
     break 
    circularity = 4*math.pi*(area/(perimeter*perimeter)) 
    print circularity 
    if 0.7 < circularity < 1.2: 
     contours_cirles.append(con) 

बहुत बहुत धन्यवाद! :)

example_done

+0

बहुत पुराना कोड। लेकिन आप इसे देख सकते हैं। https://github.com/bipul21/ रंगीन- बॉल- –

+0

'(क्षेत्र/परिधि * परिधि) 'यह मेरे लिए अजीब लग रहा है। क्या आप वाकई किसी भी ब्रैकेट को नहीं भूल गए हैं? – Moritz

+0

हाँ, आप सही हैं। परिपत्र = 4 * math.pi * (क्षेत्र/(परिधि * परिधि)) – cmplx96

उत्तर

4

एक प्रारंभिक बिंदु के रूप में आप के साथ शुरू हो सकता है:

    :

    • प्रत्येक समोच्च से अधिक cv2.findContours()
    • दोहराएं का उपयोग कर दिए गए छवि में सभी आकृति का पता लगाएं
    • क्षेत्र की गणना करें, यदि समोच्च का क्षेत्र किसी दिए गए श्रेणी में है 70 < area < 150 कहें। यह कुछ बेहद छोटे और बड़े रूपों को फ़िल्टर करेगा।
    • क्षेत्र थ्रेसहोल्ड के साथ समोच्चों को फ़िल्टर करने के बाद, आपको समोच्च के किनारों की संख्या की जांच करने की आवश्यकता है, जो cv2.approxPolyDP() का उपयोग करके किया जा सकता है, एक सर्कल लेन (लगभग) होना चाहिए> 8 लेकिन < 23. या आप यहां मंडलियों का पता लगाने के लिए कुछ और परिष्कृत परिचालन लागू करें।

आप इस दृष्टिकोण को लागू करने और कोड है कि आप आगे से लिखेंगे साथ सवाल अद्यतन करने के लिए प्रयास करना चाहिए।

संपादित करें: @Miki ने सुझाव दिया, वहाँ का पता लगाने के लिए एक बेहतर और क्लीनर तरीका है अगर एक ज्यामितीय आकार घेरा = 4pi (क्षेत्र/परिधि^2) का उपयोग कर गोल आकार का है, और एक सीमा तय जैसे 0.9, यह जांचने के लिए कि आकार परिपत्र है या नहीं। सही सर्कल circularity == 1 के लिए। आप अपनी जरूरतों के अनुसार इस दहलीज को अच्छी तरह से ट्यून कर सकते हैं।

परिपत्र की परिधि की गणना करने के लिए आवश्यक समोच्च क्षेत्र प्राप्त करने के लिए आप समोच्च परिधि और contourArea को खोजने के लिए arcLength से परामर्श ले सकते हैं।

+4

मैं यह मापने के लिए _circularity_ का उपयोग करूंगा कि आकार कितना एक चक्र है: "परिपत्र को इस प्रकार परिभाषित किया गया है: एक उपाय आकार के चक्र के करीब कितना उपाय है। जैसे नियमित हेक्सागोन में वर्ग के मुकाबले उच्च परिपत्र होता है। (\ frac {4 * \ pi * क्षेत्र} {परिधि * परिधि})। इसका मतलब है कि एक सर्कल में 1 की गोलाकारता होती है, वर्ग की परिपत्र 0.785 है, और इसी तरह। " – Miki

+1

बहुत बहुत धन्यवाद @ मिकी – ZdaR

1

हम छवि में हलकों का पता लगाने और थ्रेसहोल्ड साथ खेलने के लिए बहुत Hough Transformation कोशिश वांछित परिणाम (पता चला हलकों केन्द्रों के रूप में लाल डॉट्स के साथ हरे रंग की सीमा रेखा में) प्राप्त करने के लिए कर सकते हैं:

import cv2 
import numpy as np 

img = cv2.imread('rbv2g.jpg',0) 
img = cv2.medianBlur(img,5) 
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,10, 
          param1=50,param2=12,minRadius=0,maxRadius=20) 

circles = np.uint16(np.around(circles)) 
for i in circles[0,:]: 
    # draw the outer circle 
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) 
    # draw the center of the circle 
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 

cv2.imshow('detected circles',cimg) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

enter image description here

संबंधित मुद्दे