8

Xin chào mục tiêu của tôi là phát triển chức năng theo dõi đầu để sử dụng trong buồng lái (mô phỏng) buồng lái, để cung cấp AR để hỗ trợ phi công dân sự hạ cánh và bay với điều kiện thị giác kém.Làm thế nào tôi có thể ước tính máy ảnh đặt ra với các tương tác từ 3d đến 2d (sử dụng opencv)

Cách tiếp cận của tôi là phát hiện các điểm đặc trưng (trong các đèn LED mô phỏng tối) mà tôi biết tọa độ 3D và tính toán (máy ảnh đeo đầu) ước tính [R | t] (xoay ghép với bản dịch).

Vấn đề tôi có là ước tính gây ra có vẻ là luôn luôn sai và dự báo của các điểm 3D của tôi (mà tôi cũng sử dụng để ước tính tư thế) không trùng với các điểm ảnh 2D (hoặc không nhìn thấy được).

LED detection works but pose estimation and 3D projection not

Câu hỏi của tôi là:

Làm thế nào tôi có thể ước tính camera chụp hình với một tập hợp các thư từ điểm 2D-to-3D.

Tại sao nó không hoạt động như thế nào tôi thử nó và nơi có thể là nguồn lỗi?

Độ chính xác phải là số đo (điểm 3D và 2D và ma trận máy ảnh) để có được giải pháp lý thuyết hoạt động trong môi trường thực tế?

Cách tiếp cận có hoạt động cho các điểm đồng phẳng (x, trục y thay đổi) theo lý thuyết không?

Phần cứng tôi sử dụng là Epson BT-200.

Trên máy bay, tôi đã xác định một thứ tự cố định mà tôi mong đợi các bản dịch và phép quay tương đối do chương trình của tôi. Chương trình phát hiện tọa độ hình ảnh của các đèn LED (duy nhất) và kết hợp chúng với tọa độ 3D tương ứng của chúng. Với một ma trận máy ảnh tôi thu được bằng cách sử dụng mã android mẫu open-cv (https://github.com/Itseez/opencv/tree/master/samples/android/camera-calibration), tôi cố gắng ước tính tư thế bằng cách sử dụng giải pháp.

Ma trận máy ảnh và biến dạng của tôi hơi biến đổi một chút. Dưới đây là một số giá trị tôi nhận được từ quy trình. Tôi đảm bảo rằng khoảng cách vòng tròn của mẫu vòng tròn in ra của tôi giống như được viết trong mã nguồn (được đo bằng Mét).

Dưới đây là một số ví dụ và cách tôi tạo Mat OpenCV của nó.

// protected final double[] DISTORTION_MATRIX_VALUES = new double[]{ 
//   /*This matrix should have 5 values*/ 
//   0.04569467373955304, 
//   0.1402980385369059, 
//   0, 
//   0, 
//   -0.2982135315849994 
// }; 

// protected final double[] DISTORTION_MATRIX_VALUES = new double[]{ 
//   /*This matrix should have 5 values*/ 
//   0.08245931646421553, 
//   -0.9893762277047577, 
//   0, 
//   0, 
//   3.23553287438898 
// }; 

// protected final double[] DISTORTION_MATRIX_VALUES = new double[]{ 
//   /*This matrix should have 5 values*/ 
//   0.07444480392067945, 
//   -0.7817175834131075, 
//   0, 
//   0, 
//   2.65433773093283 
// }; 
    protected final double[] DISTORTION_MATRIX_VALUES = new double[]{ 
      /*This matrix should have 5 values*/ 
      0.08909941096327206, 
      -0.9537960457721699, 
      0, 
      0, 
      3.449728790843752 
    }; 

    protected final double[][] CAMERA_MATRIX_VALUES = new double[][]{ 
      /*This matrix should have 3x3 values*/ 
//   {748.6595405553738, 0, 319.5}, 
//   {0, 748.6595405553738, 239.5}, 
//   {0, 0, 1} 
//   {698.1744297982436, 0, 320}, 
//   {0, 698.1744297982436, 240}, 
//   {0, 0, 1} 
//   {707.1226937511951, 0, 319.5}, 
//   {0, 707.1226937511951, 239.5}, 
//   {0, 0, 1} 
      {702.1458656346429, 0, 319.5}, 
      {0, 702.1458656346429, 239.5}, 
      {0, 0, 1} 
    }; 

    private void initDestortionMatrix(){ 
     distortionMatrix = new MatOfDouble(); 
     distortionMatrix.fromArray(DISTORTION_MATRIX_VALUES); 
    } 

    private void initCameraMatrix(){ 
     cameraMatrix = new Mat(new Size(3,3), CvType.CV_64F); 
     for(int i=0;i<CAMERA_MATRIX_VALUES.length; i++){ 
      cameraMatrix.put(i, 0, CAMERA_MATRIX_VALUES[i]); 
     } 
    } 

Để ước tính máy ảnh pose Tôi sử dụng solvePnP (và solvePnPRansac) như mô tả ở một số địa điểm (1, 2, 3, 4). Kết quả của solutionPnP tôi sử dụng làm đầu vào cho Projection (Calib3d.projectPoints). Nghịch đảo của kết quả concatinated [R | t] Tôi sử dụng như là tư thế ước tính.

Vì kết quả của tôi trong môi trường sản xuất quá tệ nên tôi đã tạo môi trường thử nghiệm. Trong môi trường đó, tôi đặt máy ảnh (đó là vì hình dạng 3D của nó (đó là một chiếc kính) hơi xoay xuống ở cạnh của một chiếc bàn, cạnh này tôi sử dụng như một hệ thống phối hợp thế giới.Tôi đã tìm kiếm cách mà hệ tọa độ mở-cv có thể được định hướng và tìm ra các câu trả lời khác nhau (một trên stackoverflow và một trong một bài nói chuyện chính thức về opencv trên youtube). Dù sao thì tôi đã thử nghiệm nếu tôi có hệ tọa độ phải bằng cách chiếu các điểm 3D (được mô tả trong hệ tọa độ đó) trên một hình ảnh và kiểm tra xem hình dạng thế giới đã cho không thay đổi.

Vì vậy, tôi đã đưa ra w chỉ z đầu, y xuống và x ở bên phải. The image shows that the 3D pattern is projected correctly. Only the pose is not esitmated so the points do not overlap

Để đến gần hơn với giải pháp của tôi, tôi đã ước tính tư thế trong môi trường thử nghiệm của tôi. Kết quả đầu ra của đầu ra vector và đầu ra của thiên hà có nghĩa là nghịch đảo của [R | t]. Các thiên thần euler có thể không được hiển thị chính xác (chúng có thể bị hoán đổi hoặc sai, nếu chúng ta xem xét) vì tôi tính toán nó với phương trình convetional (tôi giả định hệ tọa độ máy bay), sử dụng hệ tọa độ open-cv. (Việc tính toán xảy ra trong lớp Pose mà tôi sẽ đính kèm). Nhưng dù sao thì vector dịch (của nghịch đảo) xuất hiện là sai (trong bài kiểm tra đơn giản của tôi). enter image description here

Trong một thử nghiệm với hình ảnh mà tôi đã có một cuộn (có thể sân trong máy bay tọa độ) 30 ° và một lên bản dịch của 50 cm. Điều đó dường như hợp lý hơn. Vì vậy, tôi giả định vì điểm của tôi là đồng phẳng, tôi có thể nhận được kết quả mơ hồ. Vì vậy, tôi đã nhận ra một bài kiểm tra khác với một điểm đã thay đổi trong Z-Axis. Nhưng với thử nghiệm này ngay cả khi chiếu không thành công. enter image description here

Đối với giải phápPnP, tôi đã thử tất cả các giải thuật-giải thuật khác nhau và các tham số khác nhau cho ransac algorithm.

Có thể bạn bằng cách nào đó có thể giúp tôi tìm ra sai lầm của mình, hoặc chỉ cho tôi một con đường tốt để giải quyết vấn đề ban đầu của tôi. Tôi cũng sẽ đính kèm mã nguồn gỡ rối của tôi với nhiều câu lệnh println và các hình ảnh gỡ lỗi. Mã này chứa số đo điểm của tôi.

Cảm ơn sự giúp đỡ của bạn trước.

Lớp Main.java: Lớp Pose.java: 0.png enter image description here

1.png enter image description here

EDIT 2015/03/22: Cuối cùng tôi có đã có thể tìm thấy những sai lầm tôi đã thực hiện.

  1. Tôi đã sửa đổi đối tượng Mat trong vòng lặp, vì OpenCV hoạt động rất nhiều với cuộc gọi bằng tham chiếu và tôi không cẩn thận ở đây. Vì vậy, tvec và rvec cho việc chiếu lại không đúng.
  2. Một trong những điểm của tôi trong môi trường thử nghiệm có (trong hình ảnh tọa độ), đã được gắn thẻ sai do nhầm lẫn hướng trục.

Vì vậy, cách tiếp cận của tôi nói chung là đúng. Tôi không nhận được ít nhất (thường xuyên) reprojections hợp lệ trong bộ dữ liệu thử nghiệm của tôi.

Thật không may các thuật toán PnP của OpenCV: "ITERATIVE, P3P, EPNP" trả về các kết quả khác nhau, và thậm chí với việc đoán rất nội tại nhưng không chính xác nhưng gần đúng. P3P algorithm được cho là cung cấp 3 giải pháp, nhưng OpenCV chỉ cung cấp một giải pháp. EPNP là nghĩa vụ phải trả lại kết quả tốt, nhưng với EPNP OpenCV trả về kết quả tồi tệ nhất, được đánh giá từ sự che khuất của con người tôi.

Vấn đề bây giờ là, cách lọc các giá trị không chính xác hoặc đảm bảo hàm OpenCV trả về giá trị hợp lệ. (Có lẽ tôi shuold sửa đổi mã nguồn gốc để nhận được 3 giải pháp cho PnP).

compressed images here(37MB), hiển thị kết quả hiện tại của tôi (với ITERATIVE PnP-Solver), với dự đoán nội tại là xoay vòng không và 75 cm trở lên. Bản in ra có trục x trục trước, trục y ở bên trái và z-xuống, và góc cuộn, độ dốc và góc yawros.

+0

Tôi thấy rằng thứ tự điểm ảnh của tôi theo tọa độ y là sai. (Tôi đã có một trục y up-pointnig trong tọa độ hình ảnh). Giá trị của tôi trở nên gần gũi hơn nhưng vẫn chưa đủ tốt. –

+1

Tôi tìm thấy bây giờ các giấy tờ và EPNP có thể sử dụng cho các điểm đồng phẳng: P3P: http://www.mmrc.iss.ac.cn/~xgao/paper/ieee.pdf EPNP: http: // cvlabwww .epfl.ch/~ lepetit/papers/lepetit_ijcv08.pdf –

+0

Tôi đã thay đổi tham số của kích thước hình vuông trong ví dụ hiệu chuẩn của tôi từ mét thành cm nhưng nhận được ma trận gần bằng nhau! –

Trả lời

3

Một điều mà tôi đã học được khi cố gắng triển khai hệ thống theo dõi đầu của tôi là bạn nên bắt đầu từ vấn đề đơn giản và di chuyển đến một vấn đề phức tạp hơn. Câu hỏi của bạn là khá ong và không may tôi không có thời gian để phân tích nó và tìm kiếm một lỗi hoặc sai lầm hợp lý trong mã của bạn, vì vậy ít nhất tôi sẽ cố gắng cung cấp cho bạn một số gợi ý và ví dụ làm việc.

Here là hướng dẫn OpenCV để tìm dịch và xoay đối tượng. Nó được viết bằng Python, nếu nó là một vấn đề here một phần của dự án C++ cũ của tôi.
Dự án của tôi thực hiện cùng một tác vụ bằng hàm resolvePnP hoặc resolvePnPRansac (bạn có thể thay đổi chế độ). Lưu ý rằng mã của tôi là một phần của một số dự án "sân chơi" cũ, vì vậy ngay cả sau khi cleaining mà tôi thực hiện nó khá lộn xộn. Khi bạn chạy nó, hiển thị bàn cờ được in cho máy ảnh, nhấn 'p' để bắt đầu vị trí và ước tính xoay vòng, 'm' để thay đổi chế độ (0-ransac, 1-pnp, 2-posit dường như không hoạt động ...) hoặc 'd' để bật/tắt bằng cách sử dụng các hệ số giải thể.
Cả hai dự án đều dựa vào việc tìm kiếm mẫu bàn cờ, nhưng nó dễ dàng sửa đổi chúng để sử dụng một số đối tượng khác.

Hiệu chỉnh máy ảnh - trong khi tôi đang làm việc trên hệ thống theo dõi đầu, tôi chưa bao giờ quản lý máy ảnh hai lần với cùng kết quả ... Vì vậy, tôi quyết định sử dụng một số tệp calibartion mà tôi đã tìm thấy trên github và nó hoạt động tốt - here bạn có thể tìm thấy một litte thông tin thêm về một liên kết đến tập tin này.

chỉnh sửa:

Cố gắng bắt đầu với đơn giản như giải pháp khả thi mà cho kết quả tốt trong một số tình huống (thậm chí đơn giản). Một điểm tốt để bắt đầu trong quan điểm của tôi là để thay thế một tờ giấy từ môi trường thử nghiệm của bạn với bàn cờ in từ hướng dẫn (this one) và làm cho nó hoạt động. Di chuyển từ điều này đến vấn đề của bạn sẽ dễ dàng hơn nhiều so với việc bắt đầu với bạn. Cố gắng đưa ra giải pháp làm việc trong bất kỳ ngôn ngữ lập trình nào - hãy xem xét sử dụng phiên bản OpenCV của Python hoặc C++ - có nhiều hướng dẫn/ví dụ hơn so với phiên bản Java và so sánh kết quả từ mã của bạn với kết quả từ một số mã làm việc. Khi bạn sẽ có một số giải pháp làm việc hãy thử sửa đổi nó để làm việc với môi trường thử nghiệm của bạn. Có rất nhiều thứ có thể khiến nó không hoạt động ngay bây giờ - không đủ điểm, lỗi trong mã của bạn hoặc thậm chí trong trình bao bọc Java OpenCV, giải thích xấu các kết quả, v.v ...

edit2:

Sử dụng điểm từ mã của bạn tôi đã quản lý để có được kết quả như sau:

rvec = [[-158,56293283], [1,46777938], [-17,32569125] ]
tvec = [[-36,23910413], [-82,83704819], [266,03157578]]

Unfortunetely, đối với tôi đó là khó có thể nói liệu kết quả có tốt hay không ... Điều duy nhất có thể là sai với tôi là 2 góc khác 0 (hoặc 180). Nhưng nếu bạn thay đổi dòng cuối cùng của points2d từ (355,37), (353,72), (353,101) để

(355,37), (35 , 72), (35 , 101)

(tôi đoán đó là sai lầm của bạn, không phải là một kết quả chính xác), bạn sẽ nhận được:

rvec = [[-159,34101842], [1,04951033], [-11,43731376]]
tvec = [[-25,74308282], [-82,58 461674], [268.97]]

có thể gần với kết quả chính xác hơn. Thay đổi các thay đổi ma trận máy ảnh sẽ dẫn đến nhiều kết quả, vì vậy hãy xem xét các giá trị thử nghiệm từ this post.

Lưu ý rằng tất cả các giá trị rvec được nhân với 180.0/3.14 - trong C++ và vector rvec python được trả về bởi resolvePnPRansac chứa các góc theo radian.

+0

Tôi đã thử ngay bây giờ để làm nó với homography nhưng một lần nữa tôi nhận được các giá trị mà không có ý nghĩa. http://stackoverflow.com/questions/8927771/computing-camera-pose-with-homography-matrix-based-on-4-coplanar-points –

+0

Cảm ơn rất nhiều vì nỗ lực của bạn. Trong môi trường sản xuất của tôi, tôi rất gần. Tôi đã có một sai lầm trong phần chiếu lại. Như đã đề cập trong các bình luận ở trên, trong môi trường thử nghiệm và mã gỡ rối, toạ độ y của các điểm 2d, chỉ vào hướng sai. Tôi thấy rằng việc thay đổi 2 pixel dẫn đến thay đổi kết quả. Cải thiện tính chính xác sẽ là vấn đề tiếp theo cần giải quyết. Tôi sẽ đăng cập nhật trạng thái hiện tại và những gì đã giúp càng sớm càng tốt. –

+0

Làm 2 pixel thực sự tạo ra sự khác biệt lớn như vậy? Các phép đo phải chính xác đến mức nào? Bây giờ tôi đã đính kèm trạng thái hiện tại của tôi trong câu hỏi. Các vòng tròn là backprojections. Cũng được hiển thị là nơi phát hiện của tôi ước tính LED và thế giới và tọa độ 2d và góc độ và đoán đoán. –

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