2016-04-13 9 views
12

में सुधार मुझे एक वीडियो से सड़क लेन का पता लगाने की आवश्यकता होगी। इसे करने का मेरा तरीका यहां है।पायथन और ओपनसीवी - मेरे लेन का पता लगाने एल्गोरिदम

  1. ब्याज (आरओआई) के क्षेत्र का निर्धारण छवि (मध्य भाग ध्यान केंद्रित)
  2. ग्रेस्केल आरओआई
  3. Equalized cv2.equalizeHist
  4. साथ grayscaled लागत पर लाभ के लिए (3)
  5. गाऊसी कलंक लागू करने की क्रिया के द्वारा
  6. थ्रेसहोल्ड (4) द्वारा skimage.morphology.skeletonize
  7. का उपयोग कर लागू 012,323 से cv2.adaptiveThreshold
  8. छोटे से छोटा करना (5) का उपयोग करते हुए(6)

cv2.HoughLines के लिए पर, मैं इतना की स्थापना की है कि:

  1. तो rho सकारात्मक है (जिसका अर्थ है सीधी रेखा सही (नीचे-ऊपर) के लिए झुका हुआ है, यह होगा केवल लाइन को खींचें यदि यह कुछ कोणों पर है (मैंने कोण की सीमा निर्धारित की है))
  2. यदि rho नकारात्मक है (सीधी रेखा बाईं ओर (नीचे-ऊपर) ढलान है, तो यह केवल रेखा को खींच लेगी कुछ कोणों पर है)

यह लाइनों ड्राइंग के लिए मेरे कोड है:

lines = cv2.HoughLines(image_bin, 1, np.pi/180, 50) 
    try: 
     range = lines.shape[0] 
    except AttributeError: 
     range = 0 

    for i in xrange(range): 
     for rho, theta in lines[i]: 
      if rho > 0 and (np.pi*1/10 < theta < np.pi*4/10): 
       a = np.cos(theta) 
       b = np.sin(theta) 
       x0 = a * rho 
       y0 = b * rho 
       x1 = int(x0 + 1000 * (-b)) 
       y1 = int(y0 + 1000 * (a)) 
       x2 = int(x0 - 1000 * (-b)) 
       y2 = int(y0 - 1000 * (a)) 

       cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0)) 

      if rho < 0 and (np.pi*7/10 < theta < np.pi*9/10): 
       a = np.cos(theta) 
       b = np.sin(theta) 
       x0 = a * rho 
       y0 = b * rho 
       x1 = int(x0 + 1000 * (-b)) 
       y1 = int(y0 + 1000 * (a)) 
       x2 = int(x0 - 1000 * (-b)) 
       y2 = int(y0 - 1000 * (a)) 

       cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0)) 

अगर मैं क्या मैं सिर्फ cv2.HoughLines समारोह के लिए ऊपर किया नहीं किया, मेरा मानना ​​है कि तैयार की अनावश्यक लाइनों का एक बहुत होगा।

पैरामीटर को समायोजित करने के बाद और मुझे, मुझे काफी अच्छा परिणाम मिला लेकिन यह केवल एक तस्वीर के लिए है। मुझे नहीं लगता कि यह एक ऐसे वीडियो के लिए अच्छा होगा जो बदलता रहेगा। मुझे आवश्यक लाइनों (जो सड़क लेन है) ड्राइंग के लिए मेरे एल्गोरिदम के बारे में सबसे ज्यादा परेशान करता है। क्या कोई बेहतर तरीका है? मेरे से कम से कम बेहतर।

यह मेरा परिणाम है:

मूल छवि: The original image

Equalized हिस्टोग्राम, thresholded, और लागत पर लाभ की skeletonized छवि: Equalized Histogram, thresholded, and skeletonized

अंतिम परिणाम: Final result

उत्तर

6

मैं आपके आवेदती के लिए संभाव्य हौ लाइन ट्रांसफॉर्म का उपयोग करने पर विचार करने की सलाह दूंगा पर। ओपनसीवी के पायथन एपीआई में, यह फ़ंक्शन में लागू किया गया है, cv2.HoughLinesP। यह वास्तव में आपको लाइन सेगमेंट देगा, इसलिए आपको एंडपॉइंट्स की गणना करने की आवश्यकता नहीं होगी। यह मानक हौ लाइन ट्रांसफॉर्म से भी तेज है।

हालांकि कुछ व्यापार-बंद हैं। उदाहरण के लिए, आपको एक साथ रेखा खंडों को सिलाई करने के लिए तर्क जोड़ने की आवश्यकता हो सकती है। दूसरी तरफ, मैंने पाया है कि यह वास्तव में एक बुरी चीज नहीं है। मेरी खिलौनों की परियोजनाओं में से एक (एक स्व-ड्राइविंग लघु बस), इस दृष्टिकोण का उपयोग करती है, और अलग-अलग रेखा खंडों को एक साथ सिलाई करने के लिए घुमावदार सड़कों से निपटना आसान बनाता है जिसमें मानक आटा लाइन परिवर्तन आपको किसी भी लाइन नहीं देगा ।

उम्मीद है कि मदद करता है।

संपादित करें: रेखा खंड "सिलाई" के विवरण के बारे में, यह उस पर निर्भर करता है जो आप पूरा करना चाहते हैं। यदि आप बस सड़क प्रदर्शित करना चाहते हैं, और आप लाइन सेगमेंट के बीच कुछ अंतर होने से संतुष्ट हैं, तो आपको किसी भी सिलाई करने की आवश्यकता नहीं हो सकती है - बस सभी लाइन सेगमेंट प्रदर्शित करें। मेरे आवेदन में, मुझे लेन के वक्रता को निर्धारित करने की आवश्यकता थी, इसलिए मैंने प्रत्येक सड़क लेन के मॉडल का निर्माण करने के लिए कुछ सिलाई की, जिसमें लेन की औसत ढलान शामिल होगी - जिसका उपयोग मॉड्यूल को इनपुट के लिए जिम्मेदार मॉड्यूल में इनपुट के रूप में किया गया था तौलिए तदनुसार पहियों को स्थानांतरित करने के लिए।

"सिलाई" से मेरा मतलब कुछ भी विशेष रूप से परिष्कृत नहीं है, लेकिन मुझे इसे पूरा करने के लिए किसी विशेष ओपनसीवी कार्यों से अवगत नहीं है। मुझे बस उसी लाइन से जुड़े लाइन सेगमेंट के एक तरीके की आवश्यकता थी। इसलिए मैंने डाउनवर्ड की छवि के शीर्ष से HoughLinesP से लौटाई गई लाइन सेगमेंट को संसाधित किया, और प्रत्येक लाइन सेगमेंट की ढलान और वाई-इंटरसेप्ट का उपयोग यह निर्धारित करने के लिए किया कि लाइन सेगमेंट कहां छेड़छाड़ करेगा।

+0

मैं लाइनों को कैसे सिलाई कर सकता हूं? क्षमा करें, अभी भी प्रोग्रामिंग और छवि प्रसंस्करण दोनों में एक शुरुआत है। – Hilman

+0

मैंने कुछ नोट्स जोड़े। कोई कोड प्रदान नहीं करने के लिए खेद है। यह सी ++ में है, और विशेष कार्यान्वयन आपके से बहुत अलग है - मूल रूप से, मेरे पास आपके आवेदन के लिए इसे अनुकूलित करने के लिए पर्याप्त समय नहीं है। – Aenimated1

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