Tôi đang sử dụng máy tính bảng google tango để thu thập dữ liệu đám mây điểm và hình ảnh camera RGB. Tôi muốn tạo bản scan 3D của căn phòng. Vì vậy, tôi cần ánh xạ các điểm ảnh của điểm ảnh 2D đến điểm đám mây. Tôi sẽ làm điều này với rất nhiều đám mây điểm và hình ảnh tương ứng. Tôi cần phải viết một kịch bản mã có hai đầu vào 1. đám mây điểm và 2. hình ảnh được lấy từ cùng một điểm theo cùng một hướng và tập lệnh sẽ xuất ra điểm màu đám mây. Làm thế nào tôi nên tiếp cận này & nền tảng nào sẽ rất đơn giản để sử dụng?cách tô điểm đám mây điểm từ điểm ảnh?
Trả lời
Đây là toán học để ánh xạ một điểm 3D v
vào không gian điểm ảnh 2D trong hình ảnh camera (giả định rằng v
đã kết hợp các vị trí camera bên ngoài và định hướng, xem chú thích ở dưới *):
// Project to tangent space.
vec2 imageCoords = v.xy/v.z;
// Apply radial distortion.
float r2 = dot(imageCoords, imageCoords);
float r4 = r2*r2;
float r6 = r2*r4;
imageCoords *= 1.0 + k1*r2 + k2*r4 + k3*r6;
// Map to pixel space.
vec3 pixelCoords = cameraTransform*vec3(imageCoords, 1);
đâu cameraTransform
là ma trận 3x3:
[ fx 0 cx ]
[ 0 fy cy ]
[ 0 0 1 ]
với fx
, fy
, cx
, cy
, k1
, k2
, k3
từ TangoCameraIntrinsics
.
pixelCoords
được khai báo vec3
nhưng thực ra là 2D ở tọa độ đồng nhất. Tọa độ thứ ba luôn là 1 và vì vậy có thể bỏ qua cho các mục đích thực tế. Lưu ý rằng nếu bạn muốn tọa độ kết cấu thay vì tọa độ pixel, đó chỉ là một biến đổi tuyến tính có thể được xử lý trước lên cameraTransform
trước thời hạn (như là bất kỳ địa chỉ quét từ đầu đến cuối nào so với từ trên xuống dưới). .
Đối với "nền tảng" (mà tôi được hiểu là "ngôn ngữ") đơn giản nhất, native API có vẻ là cách đơn giản nhất để có được các điểm ảnh trên máy ảnh, mặc dù dường như mọi người cũng đã thành công với Unity và Java.
* Điểm được phân phối bởi TangoXYZij
đã kết hợp máy ảnh chiều sâu bên ngoài biến đổi. Về mặt kỹ thuật, vì máy tính bảng nhà phát triển hiện tại có cùng phần cứng giữa độ sâu và thu thập hình ảnh màu, bạn sẽ không thể có được hình ảnh màu khớp chính xác trừ khi cả thiết bị và cảnh của bạn đều dừng. May mắn thay trong thực tế, hầu hết các ứng dụng có thể giả định rằng không phải máy ảnh đặt ra cũng như cảnh thay đổi đủ trong một khung thời gian để ảnh hưởng đáng kể đến việc tra cứu màu sắc.
Câu trả lời này không phải là bản gốc, nó chỉ đơn giản là tiện lợi cho người dùng Unity muốn có câu trả lời đúng, như được cung cấp bởi @rhashimoto, đã làm việc cho họ. Đóng góp của tôi (hy vọng) là cung cấp mã mà làm giảm bình thường 16 nhân và 12 cho biết thêm (cho Unity chỉ 4x4 ma trận) đến 2 nhân và 2 cho biết thêm bằng cách bỏ tất cả các kết quả bằng không. Tôi chạy dưới một triệu điểm thông qua thử nghiệm, kiểm tra mỗi lần tính toán của tôi đồng ý với các phép tính ma trận cơ bản - được định nghĩa là sự khác biệt tuyệt đối giữa hai kết quả nhỏ hơn epsilon máy - Tôi cảm thấy thoải mái với điều này biết rằng @rhashimoto có thể hiển thị và chọc một lỗ khổng lồ trong đó :-)
Nếu bạn muốn chuyển đổi qua lại, hãy nhớ đây là C#, vì vậy định nghĩa USEMATRIXMATH phải xuất hiện ở đầu tệp.
Do chỉ có một thiết bị Tango ngay bây giờ, và tôi giả intrinsics là liên tục trên tất cả các thiết bị, tôi chỉ đổ chúng vào như hằng số, chẳng hạn rằng
fx = 1042.73999023438
fy = 1042.96997070313
cx = 637.273986816406
cy = 352.928985595703
k1 = 0.228532999753952
k2 = -0.663019001483917
k3 = 0.642908990383148
Có họ có thể được đổ như là hằng số, điều này sẽ làm cho mọi thứ dễ đọc hơn, và C# có lẽ đủ thông minh để tối ưu hóa nó - tuy nhiên, tôi đã dành quá nhiều thời gian trong công cụ của Agner Fogg, và sẽ luôn bị hoang tưởng.
Mã nhận xét ở dưới cùng là để kiểm tra sự khác biệt, nếu bạn muốn. Bạn sẽ phải bỏ ghi chú một số nội dung khác và nhận xét lợi nhuận nếu bạn muốn kiểm tra kết quả.
tôi nhờ một lần nữa để @rhashimoto, đây là xa tốt hơn nhiều so với những gì tôi đã
Tôi đã ở đúng logic của mình, hãy nhớ đây là những tọa độ pixel, không UV phối - ông là đúng mà bạn có thể premultiply các chuyển đổi để có được giá trị UV bình thường, nhưng kể từ khi ông dạy cho tôi về vấn đề này một lần rồi, tôi sẽ gắn bó với chính xác toán học ông đã trình bày trước khi tôi fiddle với quá nhiều :-)
static public Vector2 PictureUV(Vector3 tangoDepthPoint)
{
Vector2 imageCoords = new Vector2(tangoDepthPoint.x/tangoDepthPoint.z, tangoDepthPoint.y/tangoDepthPoint.z);
float r2 = Vector2.Dot(imageCoords, imageCoords);
float r4 = r2*r2;
float r6 = r2*r4;
imageCoords *= 1.0f + 0.228532999753952f*r2 + -0.663019001483917f*r4 + 0.642908990383148f*r6;
Vector3 ic3 = new Vector3(imageCoords.x,imageCoords.y,1);
#if USEMATRIXMATH
Matrix4x4 cameraTransform = new Matrix4x4();
cameraTransform.SetRow(0,new Vector4(1042.73999023438f,0,637.273986816406f,0));
cameraTransform.SetRow(1, new Vector4(0, 1042.96997070313f, 352.928985595703f, 0));
cameraTransform.SetRow(2, new Vector4(0, 0, 1, 0));
cameraTransform.SetRow(3, new Vector4(0, 0, 0, 1));
Vector3 pixelCoords = cameraTransform * ic3;
return new Vector2(pixelCoords.x, pixelCoords.y);
#else
//float v1 = 1042.73999023438f * imageCoords.x + 637.273986816406f;
//float v2 = 1042.96997070313f * imageCoords.y + 352.928985595703f;
//float v3 = 1;
return new Vector2(1042.73999023438f * imageCoords.x + 637.273986816406f,1042.96997070313f * imageCoords.y + 352.928985595703);
#endif
//float dx = Math.Abs(v1 - pixelCoords.x);
//float dy = Math.Abs(v2 - pixelCoords.y);
//float dz = Math.Abs(v3 - pixelCoords.z);
//if (dx > float.Epsilon || dy > float.Epsilon || dz > float.Epsilon)
// UnityEngine.Debug.Log("Well, that didn't work");
//return new Vector2(v1, v2);
}
là một lưu ý cuối cùng, làm chú ý mã mà anh ấy cung cấp là GLSL - nếu bạn chỉ sử dụng nó cho những bức ảnh đẹp, hãy sử dụng nó - điều này là dành cho những người thực sự cần thực hiện thêm chế biến itional.
- 1. Thân lồi 3D từ đám mây điểm
- 2. Thư viện đám mây điểm, đăng ký mạnh mẽ của hai đám mây điểm
- 3. Thêm hai đám mây điểm khác nhau vào trình xem (Thư viện điểm đám mây (PCL))
- 4. Chia lưới các đám mây điểm từ máy quét 3Dlaser
- 5. Bộ sưu tập điểm cuối đám mây Tham số
- 6. Chỉ nhận được các điểm "hợp lệ" trong nội suy 2D của điểm đám mây sử dụng Scipy/Numpy
- 7. Thuật toán để tạo lưới tam giác từ một đám mây điểm
- 8. Cách chấm điểm hệ thống lưu trữ đám mây như Amazon S3
- 9. Cách hiển thị đám mây điểm trong vtk với các màu khác nhau?
- 10. Tạo một đám mây điểm PCL bằng cách sử dụng một hộp chứa Eigen Vector3d
- 11. Lưu trữ dữ liệu đám mây điểm ARKit và truy xuất để hiển thị
- 12. Điểm ảnh trộn từ hai ảnh bitmap
- 13. tô điểm JSON Mảng trong JavaScript
- 14. tô điểm mã bên trong một textarea
- 15. Thuật toán tái tạo bề mặt kín nước cho đám mây điểm có tổ chức
- 16. Diện tích được bao phủ bởi một đám mây điểm với R
- 17. Tìm vòng tròn/hình elip bên trong của đám mây điểm 2D
- 18. phương thức điểm cuối đám mây của google với nhiều thông báo phản hồi
- 19. Biểu diễn thưa thớt voxel của dữ liệu đám mây điểm
- 20. Tạo dự án với PCL (Thư viện đám mây điểm) trên Mac OS X
- 21. Cách lấy ảnh của một địa điểm từ bản đồ google hoặc địa điểm API
- 22. Cách lấy hình ảnh điểm tham quan thành phố từ API Google Địa điểm
- 23. Cách tìm điểm ảnh xa nhất với điểm ảnh khác trong cùng nhóm pixel
- 24. Tái thiết lập điểm 3D từ nhiều điểm 2D?
- 25. Tái thiết lập điểm 3D từ hai điểm 2D?
- 26. Điểm nổi bật của điểm ảnh không xuất hiện
- 27. Cách tính góc từ điểm?
- 28. Làm cách nào để chọn ngẫu nhiên điểm k từ N điểm trong MATLAB?
- 29. Chuyển đổi điểm từ hình ảnh sang điểm UIImageView, contentMode-aware
- 30. Điểm ảnh SVG trong chrome