2016-05-11 8 views
6

मैंने रोबोट विकसित किया है जो मक्का संयंत्र में चला सकता है और कंपास सेंसर द्वारा निर्देशित है लेकिन मैं कैमरे को रोबोट की आंख के रूप में लागू करना चाहता हूं और आंदोलन के त्रुटि कोण का पता लगाने के लिए छवि प्रसंस्करण का उपयोग करना चाहता हूं।छवि से रोबोट दिशा का पता लगाने के लिए कैसे?

यह छवि उदाहरण है।

संसाधित छवि processed image रॉ इमेज raw image हिस्सों में बंटा हुआ छवि segmented image

मैं इस निम्नलिखित कदम का उपयोग

  1. चरण 1: वर्तमान तकनीक का उपयोग मैं यह है कि सह कन्वर्ट एचएसवी के lor मूल्य से this code

  2. चरण 2 संशोधित: तो यह चयनित रंग जो भूरे या गंदगी रंग है तो मैं दो सरणी में सबसे अधिक छोड़ दिया और प्रत्येक छवि पंक्ति के भूरे या चयनित रंग का सही इकट्ठा की पहचान करेगा (एक लाल बिंदु)।

  3. चरण 3: मैं एक नीले बिंदु के रूप में एक 2 रेखीय प्रतीपगमन रेखा साजिश और एक गुलाबी बिंदु
  4. चरण 4 के रूप में प्रतिच्छेदन बिंदु की गणना: एक और छवियों के साथ गुलाबी बिंदु तुलना करने के लिए हरे रंग की रेखा खींचें। मैं क्या यह हरे रंग की रेखा के साथ अभी तक
  5. समस्या गंदगी है या भूरे रंग मकई पत्ती के बीच मौजूद भी तो मैं एक गणना

याद आती है सवाल यह है कि मेरे कोड बनाने के है क्या करने के लिए यकीन नहीं है मकई के पत्ते या किसी अन्य क्षेत्र के बीच ब्राउन पिक्सेल को फ़िल्टर करने के लिए जो मक्का पथ में नहीं है? इस समस्या में मुझे कौन सी एल्गोरिदम या पद्धति का अध्ययन करना चाहिए या आवेदन करना चाहिए?

EDIT1: Spektre के जवाब का उपयोग करते हुए और यह बाद मैं जावा + Boofcv

  • चरण 1 के साथ इसे लागू बेहतर

    यहाँ परिणाम है दिखता है: थ्रेशोल्डिंग या रंग विभाजन Thresholding or Color Segmentation

  • चरण 2: धुंधला (गाऊशियन और मध्य फ़िल्टर का उपयोग करें) Blured

  • चरण 3: प्लॉट रैखिक प्रतिगमन Plot Linear Regression

अधिक जानकारी

Full Code Here

LinearRegression Class

10 example images with the same process

+0

साथ घुमाव के रूप में मैं सवाल है कि एक सटीक सूत्रीकरण (कई उपयोगी "दृष्टि/सीखने" जैसी समस्याओं) बहुत व्यापक नहीं है पर विचार करेंगे। मेरी इच्छा है कि उन्हें समर्पित एक और नेटवर्क साइट थी, लेकिन मुझे कोई नहीं मिला। –

+1

सभ्य आकार का एक औसत फ़िल्टर, 9x 9 की तरह अधिकांश चीजों से छुटकारा पाना चाहिए। आप अधिकतम और न्यूनतम फ़िल्टर को गठबंधन करने का भी प्रयास कर सकते हैं। – Piglet

+0

@ पिगलेट धन्यवाद। मैं छोटे कण से छुटकारा पाने के लिए आपके सुझाव के रूप में मध्य फ़िल्टर लागू करता हूं। संपादित पोस्ट देखें। –

उत्तर

3

अपने स्रोत छवि

source

मैं करूंगा के लिए:

  1. भूरे रंग के सामान

    का मुखौटा बनाने के बस H,S treshold और V की अनदेखी, आप पहले से ही इस की है। मैं बाद की गणना के लिए रंग (ब्लू) के बजाय पूर्णांक 255 का उपयोग करता हूं।

    mask

  2. कलंक मुखौटा

    यह गलत तरीके से चयनित भागों के छोटे समूहों को हटा देगा।इसके बाद आपको मास्क को फिर से रोकना चाहिए क्योंकि मुखौटा मान 255 तब छोटा होगा जब तक कि आप पूरी तरह से चयनित क्षेत्र नहीं प्राप्त कर लेते। क्षेत्र जितना बड़ा होगा उतना बड़ा मूल्य (255 के करीब)। मैं >=150

  3. साथ treshold क्षैतिज लाइनों द्वारा मुखौटा स्कैन

  4. प्रत्येक पंक्ति के लिए सभी चयनित पिक्सल के गुरुत्वाकर्षण का केंद्र खोजने के

    धुंधला और tresholding फिर से इस्तेमाल किया नकाब में हो जाने के बाद एक्वा। तो औसत बिंदु x प्रत्येक पंक्ति में सभी मुखौटा पिक्सेल के समन्वय की गणना करें। इस बिंदु को सफेद के साथ चिह्नित किया गया है।

    गुरुत्वाकर्षण

    के केन्द्रों में से सभी के माध्यम से

  5. वापसी लाइन मैं मेरा इस के लिए approximation search का उपयोग लेकिन आप किसी भी प्रतिगमन आप चाहते हैं का उपयोग कर सकते हैं। वहीं लाइन लाल

    के साथ चिह्नित है मैं लाइन समीकरण इस्तेमाल किया x=x0+y*dx जहां y=<0,pic1.ys>। और अंतराल पर समाधान खोज:

    x0=<-pic1.xs,+2*pic1.xs> 
    dx=<-10,+10> 
    

कहाँ pic1.xs,pic1.ys छवि संकल्प है। तो जैसा कि आप देख सकते हैं कि मैं कोणों की पूरी श्रृंखला को कवर नहीं करता लेकिन मुझे लगता है कि यह उन किनारे के मामलों पर काम नहीं करेगा (क्षैतिज दिशाओं के नजदीक)। ऐसे मामलों के लिए आपको इसके बजाय वर्टिकल लाइनों पर ऐसा करना चाहिए और इसके बजाय x=y0+x*dy का उपयोग करना चाहिए।

final result

यहाँ सी ++ स्रोत मैं के साथ ऐसा किया:

picture pic0,pic1; 
     // pic0 - source img 
     // pic1 - output img 
    int x,y,h,s,v,px,pn,*p; 
    color c; 
    // copy source image to output 
    pic1=pic0; 
    pic1.save("cornbot0.png"); 
    // create brown stuff mask 
    for (y=0;y<pic1.ys;y++)    // scan all H lines 
    for (x=0;x<pic1.xs;x++)   // scan actual H line 
     { 
     c=pic1.p[y][x];     // get pixel color 
     rgb2hsv(c);      // in HSV 
     h=WORD(c.db[picture::_h]); 
     s=WORD(c.db[picture::_s]); 
     v=WORD(c.db[picture::_v]); 
     // Treshold brownish stuff 
     if ((abs(h- 20)<10)&&(abs(s-200)<50)) c.dd=255; else c.dd=0; 
     pic1.p[y][x]=c; 
     } 
    pic1.save("cornbot1.png"); 
    pic1.smooth(10);     // blur a bit to remove small clusters as marked 
    pic1.save("cornbot2.png"); 

    // compute centers of gravity 
    p=new int[pic1.ys];     // make space for points 
    for (y=0;y<pic1.ys;y++)    // scan all H lines 
     { 
     px=0; pn=0;      // init center of gravity (avg point) variables 
     for (x=0;x<pic1.xs;x++)   // scan actual H line 
     if (pic1.p[y][x].dd>=150)  // use marked points only 
      { 
      px+=x; pn++;    // add it to avg point 
      pic1.p[y][x].dd=0x00004080; // mark used points (after smooth) with Aqua 
      } 
     if (pn)       // finish avg point computation 
      { 
      px/=pn; 
      pic1.p[y][px].dd=0x00FFFFFF;// mark it by White 
      p[y]=px;     // store result for line regression 
      } else p[y]=-1;    // uncomputed value 
     } 

    // regress line 
    approx x0,dx; 
    double ee; 
    for (x0.init(-pic1.xs,pic1.xs<<1,100,3,&ee); !x0.done; x0.step()) // search x0 
    for (dx.init(-10.0 ,+10.0  ,1.0,3,&ee); !dx.done; dx.step()) // search dx 
     for (ee=0.0,y=0;y<pic1.ys;y++)         // compute actua solution distance to dataset 
     if (p[y]!=-1)             // ignore uncomputed values (no brown stuff) 
     ee+=fabs(double(p[y])-x0.a-(double(y)*dx.a)); 
    // render regressed line with Red 
    for (y=0;y<pic1.ys;y++) 
    { 
    x=double(x0.aa+(double(y)*dx.aa)); 
    if ((x>=0)&&(x<pic1.xs)) 
    pic1.p[y][x].dd=0x00FF0000; 
    } 
    pic1.save("cornbot2.png"); 
    delete[] p; 

मैं छवियों के लिए अपने खुद के picture वर्ग उपयोग करती हैं इसलिए कुछ सदस्य हैं: की

  • xs,ys आकार पिक्सेल में छवि
  • p[y][x].dd(x,y) के रूप में स्थिति 32 बिट पूर्णांक प्रकार
  • p[y][x].dw[2] पर पिक्सेल 2 डी क्षेत्रों
  • के लिए (x,y) के रूप में स्थिति 2x16 बिट पूर्णांक प्रकार पर पिक्सेल है
  • p[y][x].db[4] है आसान चैनल पहुँच के लिए 4x8 बिट पूर्णांक प्रकार के रूप में (x,y) स्थिति में पिक्सेल
  • clear(color) - साफ करता है पूरी छवि
  • resize(xs,ys) - नए संकल्प
  • करने के लिए छवि का आकार बदलता है bmp - VCL समझाया GDI
  • smooth(n) कैनवास का उपयोग के साथ बिटमैप - तेज छवि को धुंधला n बार

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

[edit1] चिकनी

यह कैसे मेरे चिकनी दिखता है की तरह है:

void picture::smooth(int n) 
    { 
    color *q0,*q1; 
    int  x,y,i,c0[4],c1[4],c2[4]; 
    bool _signed; 
    if ((xs<2)||(ys<2)) return; 
    for (;n>0;n--) 
     { 
     #define loop_beg for (y=0;y<ys-1;y++){ q0=p[y]; q1=p[y+1]; for (x=0;x<xs-1;x++) { dec_color(c0,q0[x],pf); dec_color(c1,q0[x+1],pf); dec_color(c2,q1[x],pf); 
     #define loop_end enc_color(c0,q0[x ],pf); }} 
     if (pf==_pf_rgba) loop_beg for (i=0;i<4;i++) { c0[i]=(c0[i]+c0[i]+c1[i]+c2[i])>>2; clamp_u8(c0[i]); } loop_end 
     if (pf==_pf_s ) loop_beg     { c0[0]=(c0[0]+c0[0]+c1[0]+c2[0])/ 4; clamp_s32(c0[0]); } loop_end 
     if (pf==_pf_u ) loop_beg     { c0[0]=(c0[0]+c0[0]+c1[0]+c2[0])>>2; clamp_u32(c0[0]); } loop_end 
     if (pf==_pf_ss ) loop_beg for (i=0;i<2;i++) { c0[i]=(c0[i]+c0[i]+c1[i]+c2[i])/ 4; clamp_s16(c0[i]); } loop_end 
     if (pf==_pf_uu ) loop_beg for (i=0;i<2;i++) { c0[i]=(c0[i]+c0[i]+c1[i]+c2[i])>>2; clamp_u16(c0[i]); } loop_end 
     #undef loop_beg 
     #define loop_beg for (y=ys-1;y>0;y--){ q0=p[y]; q1=p[y-1]; for (x=xs-1;x>0;x--) { dec_color(c0,q0[x],pf); dec_color(c1,q0[x-1],pf); dec_color(c2,q1[x],pf); 
     if (pf==_pf_rgba) loop_beg for (i=0;i<4;i++) { c0[i]=(c0[i]+c0[i]+c1[i]+c2[i])>>2; clamp_u8(c0[i]); } loop_end 
     if (pf==_pf_s ) loop_beg     { c0[0]=(c0[0]+c0[0]+c1[0]+c2[0])/ 4; clamp_s32(c0[0]); } loop_end 
     if (pf==_pf_u ) loop_beg     { c0[0]=(c0[0]+c0[0]+c1[0]+c2[0])>>2; clamp_u32(c0[0]); } loop_end 
     if (pf==_pf_ss ) loop_beg for (i=0;i<2;i++) { c0[i]=(c0[i]+c0[i]+c1[i]+c2[i])/ 4; clamp_s16(c0[i]); } loop_end 
     if (pf==_pf_uu ) loop_beg for (i=0;i<2;i++) { c0[i]=(c0[i]+c0[i]+c1[i]+c2[i])>>2; clamp_u16(c0[i]); } loop_end 
     #undef loop_beg 
     #undef loop_end 
     } 
    } 

यह बस औसत 3 पिक्सल

(x,y)=(2*(x,y)+(x-1,y)+(x,y-1))/4 

और उस

साथ भी ऐसा ही करने के बाद वजन
(x,y)=(2*(x,y)+(x+1,y)+(x,y+1))/4 
छवि के स्थानांतरित होने से बचने के लिए 210

। तब यह पूरी चीज n गुना लगी है और यह सब कुछ है। आप इस मामले में क्लैंप और पिक्सेल-प्रारूप विकल्पों को अनदेखा कर सकते हैं, यह pf==_pf_rgba है लेकिन यह वैसे भी केवल एक चैनल का उपयोग करता है ...dec_color,enc_color बस अनपॅक करें, 8 बिट चैनलों पर छंटनी और ओवरफ्लो समस्याओं से बचने के लिए चर के सरणी से रंगीन चैनलों को पैक करें और कोड को थोड़ा बेहतर (सरल पिक्सेल प्रारूप समर्थन के लिए)

बीटीडब्ल्यू चिकनी आधार है एक ही

0.00 0.25 0.00 
0.25 0.50 0.00 
0.00 0.00 0.00 

और

0.00 0.00 0.00 
0.00 0.50 0.25 
0.00 0.25 0.00 
+0

किस प्रकार का एल्गोरिदम आपको (या लाइब्रेरी) चिकनी() के लिए उपयोग करता है? –

+0

@SarinSuriyakoon ने सुचारू जानकारी और कोड – Spektre

+0

के साथ संपादित 1 जोड़ा है, मैं आपके अधिकांश सुझावों को लागू करता हूं और यह संपादित पोस्ट के रूप में अच्छी तरह से काम करता है। –

0

मैं सही आप भूरे रंग के अंश जो भटक ​​या पृष्ठभूमि के अन्य भागों में देखा जाता है के बारे में पूछ रहे हैं रहा है?

आपको वह अंतिम छवि कैसे मिली? मुझे लगता है कि आप मूल छवि को मुखौटा से गुणा कर चुके हैं? यहां तक ​​कि यदि आपने नहीं किया है, तो भी छवि को मौजूद होने पर आप छवि से मास्क प्राप्त कर सकते हैं (कोई भी सरल, बहुत कम थ्रेसहोल्ड करेगा)। (बेहतर मास्क प्राप्त करने के लिए मूल का एक और अधिक सटीक संस्करण अनुकूली थ्रेसहोल्डिंग लागू करें)

उस मास्क को ले जाएं और मॉर्फोलॉजिकल ऑपरेशंस का उपयोग करके इसे साफ़ करें, आपके मामले में बंद होने पर पर्याप्त होगा। मोर्फोलॉजी ऑपरेशन की एक बड़ी संख्या से बना है जो आपको एक बेहद साफ छवि मुखौटा दे सकता है। उन पर पढ़ें।

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