2013-02-06 12 views
8

मैं एक बाइनरी छवि का अभिविन्यास ढूंढने की कोशिश कर रहा हूं (जहां अभिविन्यास को जड़त्व के कम से कम पल के धुरी के रूप में परिभाषित किया जाता है, यानी क्षेत्र का कम से कम दूसरा क्षण)। मैं संदर्भ के रूप में रोबोट विजन which can be found here पर डॉ हॉर्न की पुस्तक (एमआईटी) का उपयोग कर रहा हूं।बाइनरी छवि ओरिएंटेशन

Point3d findCenterAndOrientation(const Mat& src) 
{ 
    Moments m = cv::moments(src, true); 
    double cen_x = m.m10/m.m00; //Centers are right 
    double cen_y = m.m01/m.m00; 

    double a = m.m20-m.m00*cen_x*cen_x; 
    double b = 2*m.m11-m.m00*(cen_x*cen_x+cen_y*cen_y); 
    double c = m.m02-m.m00*cen_y*cen_y; 

    double theta = a==c?0:atan2(b, a-c)/2.0; 

    return Point3d(cen_x, cen_y, theta); 
} 

OpenCV:

OpenCV का उपयोग करना, यहां मेरे समारोह, जहां ए, बी, और सी क्षेत्र के दूसरे क्षणों के रूप में (पाठ के 60 पेज) ऊपर पीडीएफ के पेज 15 पर पाया जाता है मूल (0,0) के आस-पास के दूसरे क्षणों की गणना करता है, इसलिए मुझे अक्ष के केंद्र में अक्ष को स्थानांतरित करने के लिए Parallel Axis Theorem का उपयोग करना होगा, mr^2।

केंद्र सही लग रहा है जब मैं

Point3d p = findCenterAndOrientation(src); 
rectangle(src, Point(p.x-1,p.y-1), Point(p.x+1, p.y+1), Scalar(0.25), 1); 

फोन लेकिन पूरी तरह से गलत जब मैं जड़ता का सबसे कम पल के साथ धुरी आकर्षित करने के लिए प्रयास करते हैं, इस समारोह का उपयोग कर, ऐसा लगता है:

line(src, (Point(p.x,p.y)-Point(100*cos(p.z), 100*sin(p.z))), (Point(p.x, p.y)+Point(100*cos(p.z), 100*sin(p.z))), Scalar(0.5), 1); 

इनपुट और आउटपुट के कुछ उदाहरण यहां दिए गए हैं:

enter image description here enter image description here

enter image description here enter image description here

+0

ए, बी और सी - और थेटा के लिए मूल्य क्या हैं? क्या आप उन्हें प्रिंट कर सकते हैं और खुद को समझ सकते हैं कि वे सही हैं? जब आप वस्तु को केन्द्रित करते हैं तो क्या होता है? क्या उससे मदद हुई? शुरू करने के लिए वे दो डिबगिंग कदम होंगे ... – Floris

+1

प्रारंभिक बिंदु के लिए, आपको 'm20/m00' जैसे विभाजित होना चाहिए और घटाना नहीं चाहिए। – mmgp

+0

ए, बी, सी आदि पर m.m00 भाग छवि मूल से ऑब्जेक्ट मूल तक रोटेशन के बिंदु को स्थानांतरित करने के लिए समानांतर अक्ष प्रमेय का उपयोग कर रहा है। – Jason

उत्तर

6

मैं उन्मुखीकरण के साथ कभी कभी वापस काम किया है और कोडित (मैं इसे क्षैतिज होने की उम्मीद थी) (मैं इसे खड़ी होने की उम्मीद थी) निम्नलिखित। यह मुझे वस्तु का सटीक अभिविन्यास देता है। सबसे बड़ा_कॉन्टर वह आकार है जो पता चला है।

CvMoments moments1,cenmoments1; 
      double M00, M01, M10; 

      cvMoments(largest_contour,&moments1); 
      M00 = cvGetSpatialMoment(&moments1,0,0); 
      M10 = cvGetSpatialMoment(&moments1,1,0); 
      M01 = cvGetSpatialMoment(&moments1,0,1); 
      posX_Yellow = (int)(M10/M00); 
      posY_Yellow = (int)(M01/M00); 

      double theta = 0.5 * atan(
        (2 * cvGetCentralMoment(&moments1, 1, 1))/
        (cvGetCentralMoment(&moments1, 2, 0) - cvGetCentralMoment(&moments1, 0, 2))); 
       theta = (theta/PI) * 180; 

       // fit an ellipse (and draw it) 

       if (largest_contour->total >= 6) // can only do an ellipse fit 
               // if we have > 6 points 
       { 
        CvBox2D box = cvFitEllipse2(largest_contour); 
        if ((box.size.width < imgYellowThresh->width) && (box.size.height < imgYellowThresh->height)) 
        { 

         cvEllipseBox(imgYellowThresh, box, CV_RGB(255, 255 ,255), 3, 8, 0); 
        } 
       } 
+0

पूरी तरह से काम करता है। बस केंद्रीय क्षणों में ए, बी, और सी बदल दिया। धन्यवाद! – Jason

+0

तो फिर आप अपने 'बॉक्स' से केंद्र बिंदु और कोण का उपयोग क्यों नहीं करते? आपके द्वारा किए गए सभी क्षणों की गणना का उपयोग नहीं किया जाता है ... और केंद्र बिंदु और 'बॉक्स' के कोण के समान (सी ++ में घुमावदार रैक्टेंगल) – br1

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