2013-02-06 42 views
8

Tôi đang cố gắng tìm hướng của hình ảnh nhị phân (trong đó định hướng được xác định là trục của ít nhất quán tính quán tính, tức là giây phút thứ hai của khu vực). Tôi đang sử dụng cuốn sách của Tiến sĩ Horn (MIT) về Robot Vision which can be found here làm tài liệu tham khảo.Định hướng hình ảnh nhị phân

Sử dụng OpenCV, đây là chức năng của tôi, trong đó a, b, c là những khoảnh khắc thứ hai của khu vực như được tìm thấy trên trang 15 của pdf ở trên (trang 60 của văn bản):

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 tính toán các giây phút xung quanh gốc (0,0) vì vậy tôi phải sử dụng Parallel Axis Theorem để di chuyển trục đến trung tâm của hình dạng, mr^2.

Trung tâm có vẻ đúng khi tôi gọi

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

Nhưng khi tôi cố gắng để vẽ trục với thời điểm thấp nhất của quán tính, sử dụng chức năng này, có vẻ hoàn toàn sai:

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); 

Dưới đây là một số ví dụ về đầu vào và đầu ra:

enter image description here enter image description here

(tôi mong đợi nó được dọc)

enter image description here enter image description here

(tôi mong đợi nó sẽ ngang)

+0

Giá trị cho a, b và c - và theta là gì? Bạn có thể in ra và thuyết phục chính mình rằng họ có đúng không? Điều gì sẽ xảy ra khi bạn căn giữa đối tượng? cái đó có giúp ích không? Đó sẽ là hai bước gỡ lỗi để bắt đầu ... – Floris

+1

Đối với điểm bắt đầu, bạn nên chia nhỏ như 'm20/m00' và không trừ đi. – mmgp

+0

phần m.m00 trên a, b, c, v.v. đang sử dụng định lý trục song song để di chuyển điểm quay từ nguồn gốc hình ảnh sang nguồn gốc đối tượng. – Jason

Trả lời

6

tôi làm việc với các định hướng đôi khi trở lại và mã hóa các tiếp theo. Nó trả về cho tôi định hướng chính xác của đối tượng. bigger_contour là hình dạng được phát hiện.

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

Hoạt động hoàn hảo. Chỉ cần thay đổi a, b, & c thành những khoảnh khắc trung tâm. Cảm ơn! – Jason

+0

Vậy tại sao bạn không sử dụng điểm và góc trung tâm từ hộp 'của bạn '? Tất cả các tính toán thời gian bạn làm không được sử dụng ... và giống như điểm trung tâm và góc của 'hộp' (RotatedRectangle in C++) – br1

Các vấn đề liên quan