2011-09-12 41 views
8

Tôi có 2 hình ảnh liên tiếp từ một máy ảnh và tôi muốn để ước tính sự thay đổi trong máy ảnh pose: two pictures with camera movementTrích xuất biến đổi và ma trận xoay từ homography?

tôi tính toán dòng chảy quang học:

Const MAXFEATURES As Integer = 100 
imgA = New Image(Of [Structure].Bgr, Byte)("pic1.bmp") 
imgB = New Image(Of [Structure].Bgr, Byte)("pic2.bmp") 
grayA = imgA.Convert(Of Gray, Byte)() 
grayB = imgB.Convert(Of Gray, Byte)() 
imagesize = cvGetSize(grayA) 
pyrBufferA = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) _ 
    (imagesize.Width + 8, imagesize.Height/3) 
pyrBufferB = New Emgu.CV.Image(Of Emgu.CV.Structure.Gray, Byte) _ 
    (imagesize.Width + 8, imagesize.Height/3) 
features = MAXFEATURES 
featuresA = grayA.GoodFeaturesToTrack(features, 0.01, 25, 3) 
grayA.FindCornerSubPix(featuresA, New System.Drawing.Size(10, 10), 
         New System.Drawing.Size(-1, -1), 
         New Emgu.CV.Structure.MCvTermCriteria(20, 0.03)) 
features = featuresA(0).Length 
Emgu.CV.OpticalFlow.PyrLK(grayA, grayB, pyrBufferA, pyrBufferB, _ 
          featuresA(0), New Size(25, 25), 3, _ 
          New Emgu.CV.Structure.MCvTermCriteria(20, 0.03D), 
          flags, featuresB(0), status, errors) 
pointsA = New Matrix(Of Single)(features, 2) 
pointsB = New Matrix(Of Single)(features, 2) 
For i As Integer = 0 To features - 1 
    pointsA(i, 0) = featuresA(0)(i).X 
    pointsA(i, 1) = featuresA(0)(i).Y 
    pointsB(i, 0) = featuresB(0)(i).X 
    pointsB(i, 1) = featuresB(0)(i).Y 
Next 
Dim Homography As New Matrix(Of Double)(3, 3) 
cvFindHomography(pointsA.Ptr, pointsB.Ptr, Homography, HOMOGRAPHY_METHOD.RANSAC, 1, 0) 

và có vẻ đúng, camera di chuyển sang bên trái và trở lên: optical flow Bây giờ tôi muốn tìm hiểu xem máy ảnh được di chuyển và xoay bao nhiêu. Nếu tôi khai báo vị trí máy ảnh của mình và những gì nó đang xem xét:

' Create camera location at origin and lookat (straight ahead, 1 in the Z axis) 
Location = New Matrix(Of Double)(2, 3) 
location(0, 0) = 0 ' X location 
location(0, 1) = 0 ' Y location 
location(0, 2) = 0 ' Z location 
location(1, 0) = 0 ' X lookat 
location(1, 1) = 0 ' Y lookat 
location(1, 2) = 1 ' Z lookat 

Làm cách nào để tính toán vị trí và giao diện mới?

Nếu tôi làm điều này sai hoặc nếu có phương pháp tốt hơn, mọi đề xuất sẽ rất được hoan nghênh, cảm ơn!

+0

Tôi đang cung cấp một khoản tiền 500 cho câu trả lời cho câu hỏi này http://stackoverflow.com/questions/7414809/extract-projective-homography-from-two-kinect-depth-maps – smirkingman

Trả lời

5

Vâng, những gì bạn đang xem xét ở dạng đơn giản là Pythagorean theorem problem a^2 + b^2 = c^2. Tuy nhiên khi nói đến các ứng dụng dựa trên máy ảnh, mọi thứ không phải là rất dễ dàng để xác định chính xác. Bạn đã tìm thấy một nửa chi tiết bạn cần cho "a", tuy nhiên việc tìm kiếm "b" hoặc "c" khó hơn nhiều.

The Short trả lời

Về cơ bản nó không thể được thực hiện với một máy ảnh duy nhất. Nhưng nó có thể được thực hiện với hai camera.

Các dài hơi trả lời (Nghĩ rằng tôi muốn giải thích sâu hơn, không có ý định chơi chữ)

tôi sẽ cố gắng và giải thích, nói rằng chúng ta chọn hai điểm trong hình ảnh của chúng tôi và di chuyển bên trái camera. Chúng ta biết khoảng cách từ camera của mỗi điểm B1 là 20mm và điểm B2 là 40mm. Bây giờ giả sử rằng chúng tôi xử lý hình ảnh và phép đo của chúng tôi là A1 là (0,2) và A2 là (0,4), chúng có liên quan đến B1 và ​​B2 tương ứng. Bây giờ A1 và A2 không phải là số đo; chúng là các điểm di chuyển.

Điều chúng ta phải làm là nhân sự thay đổi trong A1 và A2 với hằng số được tính toán sẽ là khoảng cách thế giới thực tại B1 và ​​B2. LƯU Ý: Mỗi loại này khác nhau theo phép đo B *. Tất cả điều này liên quan đến Angle of view hoặc thường được gọi là Field of View trong nhiếp ảnh ở những khoảng cách khác nhau. Bạn có thể tính toán chính xác hằng số nếu bạn biết kích thước của từng pixel trên CCD camera và số f của ống kính bạn có bên trong máy ảnh.

Tôi cho rằng đây không phải là trường hợp như vậy ở các khoảng cách khác nhau, bạn phải đặt một đối tượng mà bạn biết chiều dài và xem có bao nhiêu điểm ảnh cần thiết. Đóng lên, bạn có thể sử dụng một người cai trị để làm cho mọi thứ dễ dàng hơn. Với những phép đo này. Bạn lấy dữ liệu này và tạo thành một đường cong với một đường phù hợp nhất. Trường hợp trục X sẽ là khoảng cách của đối tượng và trục Y sẽ là hằng số của tỷ lệ pixel đến khoảng cách mà bạn phải nhân sự di chuyển của mình.

Vậy làm cách nào để áp dụng đường cong này. Vâng nó đoán công việc. Về lý thuyết, phép đo chuyển động A * càng lớn thì vật thể càng gần với máy ảnh. Trong ví dụ của chúng tôi tỷ lệ của chúng tôi cho A1> A2 nói 5mm và 3mm tương ứng và bây giờ chúng ta biết rằng điểm B1 đã di chuyển 10mm (2x5mm) và B2 đã di chuyển 6mm (2x6mm). Nhưng chúng ta hãy đối mặt với nó - chúng ta sẽ không bao giờ biết B và chúng ta sẽ không bao giờ có thể biết được khoảng cách di chuyển là 20 pixel của một vật thể không di chuyển xa hay một vật thể đang di chuyển xa. Đây là lý do tại sao những thứ như Xbox Kinect sử dụng cảm biến bổ sung để có được thông tin chiều sâu có thể được gắn với các đối tượng trong hình ảnh.

Những gì bạn cố gắng có thể thử với hai camera vì khoảng cách giữa các máy ảnh này được biết là chuyển động có thể được tính toán chính xác hơn (hiệu quả mà không sử dụng cảm biến độ sâu). Các toán học đằng sau điều này là vô cùng phức tạp và tôi sẽ đề nghị tìm kiếm một số bài báo về chủ đề này. Nếu bạn muốn tôi giải thích lý thuyết, tôi có thể cố gắng.

Tất cả kinh nghiệm của tôi đến từ việc thiết kế chuyển đổi video tốc độ cao và xử lý hình ảnh cho PHD của tôi để tin tưởng tôi, không thể thực hiện được với một máy ảnh, xin lỗi. Tôi hy vọng một số điều này sẽ giúp.

Cheers

Chris

[EDIT]

tôi sẽ thêm một bình luận nhưng điều này là dễ dàng hơn do phần lớn các thông tin:

Vì nó là Kinect Tôi sẽ giả sử bạn có một số thông tin liên quan đến độ sâu liên quan đến mỗi điểm nếu không bạn sẽ cần phải tìm ra cách để có được điều này.

Phương trình bạn sẽ cần phải bắt đầu với là cho Trường nhìn (FOV):

o/d = i/f

đâu:

f bằng với độ dài tiêu cự của ống kính thường được cho bằng mm (ví dụ: 18 28 30 50 là các ví dụ tiêu chuẩn)

d là đối tượng khoảng cách từ ống kính thu thập từ dữ liệu Kinect

o là kích thước đối tượng (hoặc "field of view" vuông góc với và chia cắt bởi các trục quang học).

i là kích thước hình ảnh (hoặc "trường dừng" vuông góc với và được chia đôi bởi trục quang).

Chúng tôi cần phải tính toán i, nơi o là chưa biết của chúng ta để cho i (đó là một phép đo đường chéo),

Chúng tôi sẽ cần phải kích thước của pixel trên CCD sẽ này trong micromet hoặc µm bạn sẽ cần phải tìm thông tin này ra, Để biết chúng tôi sẽ lấy nó như là 14um đó là tiêu chuẩn cho một camera tầm trung quét.

Vì vậy, đầu tiên chúng ta cần phải làm việc ra tôi chiều ngang (ih) là số pixel chiều rộng của máy ảnh nhân với kích thước của điểm ảnh CCD (Chúng tôi sẽ sử dụng 640 x 320)

vậy: ih = 640 * 14um = 8960um

= 8960/1000 = 8.96mm 

Bây giờ chúng ta cần i chiều dọc (iv) cùng một quá trình nhưng chiều cao

vậy: iv = (320 * 14um)/1000 = 4.48mm

Bây giờ i được tìm thấy bởi định lý Pythagore Pythagore lý a^2 + b^2 = c^2

vậy: i = sqrt (ih^2 _ iv^2)

= 10.02 mm 

Bây giờ chúng ta sẽ cho rằng chúng ta có một ống kính 28 mm. Một lần nữa, giá trị chính xác này sẽ phải được tìm ra. Vì vậy, phương trình của chúng tôi được sắp xếp lại để cung cấp cho chúng tôi o là:

o = (i * d)/f

Ghi o sẽ chéo (chúng tôi sẽ giả định của đối tượng hoặc điểm là 50mm đi):

o = (10.02mm * 50mm)/28mm

17.89mm 

Bây giờ chúng ta cần để làm việc ra o chiều ngang (oh) và o chiều dọc (ov) vì điều này sẽ cho chúng ta khoảng cách mỗi pixel mà đối tượng đã di chuyển. Bây giờ là FOV α CCD hoặc i là tỷ lệ thuận với o chúng tôi sẽ làm việc ra một tỷ lệ k

k = i/o

= 10.02/17.89 

= 0.56 

vậy:

o kích thước ngang (oh):

oh = ih/k

= 8.96mm/0.56 = 16mm cho mỗi pixel

o chiều dọc (ov):

ov = iv/k

= 4.48mm/0,56 = 8mm mỗi pixel

Bây giờ chúng ta có các hằng số chúng ta yêu cầu, hãy sử dụng nó trong một ví dụ. Nếu đối tượng của chúng tôi tại 50mm di chuyển từ vị trí (0,0) đến (2,4) thì các số đo trong cuộc sống thực là:

(2 * 16mm, 4 * 8mm) = (32mm, 32mm)

một lần nữa, một định lý Pythagore: a^2 + b^2 = c^2

Tổng khoảng cách = sqrt (32^2 + 32^2)

  = 45.25mm 

Phức tạp tôi biết, nhưng một khi bạn có điều này trong một chương trình dễ dàng hơn. Vì vậy, đối với mỗi điểm bạn sẽ phải lặp lại ít nhất một nửa quá trình như d sẽ thay đổi theo đó o cho mỗi điểm bạn kiểm tra.

Hy vọng điều này giúp bạn trên con đường của bạn,

Cheers Chris

+0

Cảm ơn bạn đã dành thời gian và trả lời chi tiết. Tôi có nội tại máy ảnh và do đó (tôi nghĩ) rằng vấn đề của tôi là giống như có 2 máy ảnh.Sự hiểu biết của tôi là bản thể hiện thể hiện camera2 sẽ liên quan đến camera1, thể hiện bằng độ dài khác nhau của các đường màu đỏ giữa các đối tượng địa lý. Giả sử các tính năng tốt (và bỏ qua hình học occluded cho thời điểm này), tập hợp các dòng chỉ có thể là kết quả của chuyển động đã cho. Từ hiệu chuẩn máy ảnh trên trang 191 của cuốn sách OpenCV, có vẻ như có thể thực hiện được, nhưng trig của tôi quá nghèo. Bạn đoán đúng, đó là một Kinect> ;-) – smirkingman

+0

Xin chào, tôi đã cung cấp cho bạn các tính toán cần thiết trong câu trả lời nó yêu cầu thông tin chi tiết từ Kinect. Tôi hy vọng rằng kích thước CCD và pixel có sẵn ở nơi khác trên web. Hy vọng nó sẽ giúp – Chris

+0

Cảm ơn Chris, điều đó làm cho mọi thứ trở nên rõ ràng hơn (tại sao mọi người khác luôn làm cho nó phức tạp như vậy?). Tôi bắt đầu với hình ảnh, hy vọng sử dụng luồng quang học để giúp tôi 'vị trí' dữ liệu độ sâu, rõ ràng tôi không thể lấy được khoảng cách trong thế giới thực từ hình ảnh, như bạn thấy. Bây giờ tôi có dữ liệu độ sâu, được dịch sang thế giới thực (một đám mây điểm [X, Y, Z] tính bằng milimet). Tôi vẫn còn sau khi tìm bản dịch + xoay và tôi hiểu rằng những gì tôi cần là điều chỉnh gói. Bất kỳ ý tưởng mà tôi có thể tìm thấy một ví dụ trong. NET (C# hoặc VB, C không phải là điều)? Cảm ơn một lần nữa :) – smirkingman

8

Đối tinh khiết camera xoay R = A -1 HA. Để chứng minh điều này, hãy xem xét hình ảnh đối với các đồng hồ mặt phẳng H1 = A và H2 = AR, trong đó A là ma trận nội tại của camera. Sau đó, H12 = H2 * H1 -1 = A -1 RA, từ đó bạn có thể nhận được R

Dịch máy ảnh khó ước tính hơn. Nếu máy ảnh dịch bạn phải tìm ma trận cơ bản đầu tiên (không phải là homography): x T Fx = 0 và sau đó chuyển nó thành ma trận cơ bản E = A T FA; Sau đó, bạn có thể phân tách E thành xoay và dịch E = t x R, trong đó t x nghĩa là ma trận sản phẩm vector. Phân hủy không rõ ràng, xem this.

Vòng xoay bạn nhận được sẽ chính xác trong khi chỉ có thể tìm thấy vectơ dịch ở quy mô lớn. Bằng trực giác, việc chia tỷ lệ này có nghĩa là từ hai hình ảnh một mình bạn không thể thực sự nói các vật thể gần và nhỏ hay xa và lớn. Để phân biệt chúng tôi có thể sử dụng một đối tượng kích thước quen thuộc, khoảng cách đã biết giữa hai điểm, v.v.

Cuối cùng lưu ý rằng hệ thống thị giác của con người có vấn đề tương tự: mặc dù chúng ta "biết khoảng cách giữa mắt chúng ta, khi chúng được hội tụ đối tượng chênh lệch luôn bằng không và từ chênh lệch một mình chúng ta không thể nói khoảng cách là gì. Tầm nhìn của con người dựa trên triangulation từ tín hiệu phiên bản mắt để tìm ra khoảng cách tuyệt đối.

+0

Đây là một câu trả lời rất hay và súc tích, cảm ơn! Nó sẽ xứng đáng hơn + 1s. – jhegedus

+0

h12 là homography hoặc 1 wrt 2 hoặc ngược lại, tức là p1 = h12 * p2 hoặc p2 = h12 * p1 @Vlad –

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