2011-06-12 21 views
15

के साथ समोच्च अनुमान, मैं आकृति डिटेक्शन के लिए छोटा एप्लीकेशन लिख रहा हूं। मुझे पहली जगह में क्या करने की ज़रूरत है, यह छवि पर सबसे महत्वपूर्ण आकार ढूंढना है। मैंने कुछ preprocessing से शुरू किया जिसमें छवि को ग्रेस्केल, थ्रेसहोल्डिंग और एज डिटेक्शन में कनवर्ट करना शामिल है। पहले और इन आपरेशनों के बाद छविआकृति का पता लगाने - ओपनसीवी

नीचे प्रस्तुत किया जाता है इससे पहले कि

enter image description here

enter image description here

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

cvFindContours(crated,g_storage,&contours); 

मैं जानता हूँ कि एक

cvApproxPoly 

समारोह है कि वहाँ है, तथापि मैं इस समारोह का परिणाम के लिए किसी भी उपयोगी जानकारी प्राप्त करने में सक्षम नहीं कर रहा हूँ । क्या कोई मुझे बता सकता है कि समोच्च क्षेत्र की गणना करना या बहुभुज के साथ contur अनुमानित करना संभव है। हो सकता है कि आपके पास एक बेहतर विचार है कि केवल सबसे महत्वपूर्ण आकार निकालने के लिए कैसे?

उत्तर

5

आपकी मुख्य समस्या यह है कि टावर समोच्च बिखरा हुआ है। उन छोटे टुकड़ों से पूरे समोच्च को फिर से बनाना मुश्किल होगा। अपने बढ़त का पता लगाने चरण (cvAdaptiveThreshold कोशिश) का अनुकूलन, या एक टुकड़ा में अलग दृष्टिकोण (शायद object segmentation की तरह कुछ)

का उपयोग आप अपने समोच्च है के बाद, आप इस तरह अपने क्षेत्र की जांच कर सकते हैं:

CvSeq* convex_hull=cvConvexHull2(contour, storage, CV_CLOCKWISE, 2); 
CvSeq* quad=cvApproxPoly(convex_hull, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0); 
float size=fabs(cvContourArea(quad,CV_WHOLE_SEQ,0)); 

आप होगा पैरामीटर को ट्यून करने की आवश्यकता है। इसका इस्तेमाल आयताकारों का पता लगाने के लिए किया जाता था।

8

आपको यहां किनारे का पता लगाने की ज़रूरत नहीं है। बस एक बाइनरी छवि के लिए दहलीज और फिर उस पर blobs (cvFindContours) खोजें। आप अपने क्षेत्र को खोजने के लिए प्रत्येक लौटे CvSeq पर cvContourArea का उपयोग कर सकते हैं।

2

आप अपने "समोच्च शोर" (आपके मामले में फैलाव) को दबाने के लिए मॉर्फोलॉजिकल ऑपरेशंस का उपयोग कर सकते हैं। लेकिन आपको याद रखना होगा कि मोर्फोलॉजिकल ऑपरेशंस की उपयोगिता वर्तमान कार्य पर निर्भर करती है। उदाहरण के लिए, यदि आपके पास दो ऑब्जेक्ट्स हैं जो एक दूसरे को बंद रखते हैं, तो फैलाव उनके द्वारा एक ऑब्जेक्ट कर सकता है।

6

आप हमेशा एक नियंत्रित पृष्ठभूमि है, तो मैं इन चरणों के लिए (के रूप में @damian से यह भी सुझाव दिया) जाना होगा:

  1. binarization, यानी, इस तरह के पृष्ठभूमि = 0 और रूप में एक छवि बनाने वस्तु क्षेत्र = 1 (या 255)। उसके बाद, आपके चित्र पर कई सफेद क्षेत्र होंगे। ऐसा करने के लिए कई तरीके हैं, लेकिन यदि आपकी पृष्ठभूमि नियंत्रित है तो आप एक निश्चित दहलीज का उपयोग कर सकते हैं। ध्यान दें कि यहां आपने वस्तुओं के अंदर शोर हटा दिया है।द्विआधारी छवि में आप ऑब्जेक्ट्स को सुगम बनाने के लिए हमेशा मॉर्फोलॉजिकल ओपनिंग/क्लोजिंग का उपयोग कर सकते हैं
  2. सभी ऑब्जेक्ट्स को खोजने के लिए cvFindContours का उपयोग करें: यह अब आसान होना चाहिए।
  3. cvFloodFill का उपयोग करके पृष्ठभूमि रंग के साथ छोटे रूपों को भरें।
+0

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

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