5.22. Hiệu chỉnh ống kính và phối cảnh

Có hai lớp hiệu chỉnh hình học làm biến dạng ảnh theo những cách mà ánh xạ hình chữ nhật-sang-hình chữ nhật không thể thực hiện được. Hiệu chỉnh ống kính loại bỏ méo xuyên tâm mà ống kính góc rộng thực tế gây ra -- hiệu ứng phình cá mắt làm uốn cong các đường thẳng của cảnh vật thành các đường cong rõ thấy ở góc khung hình. Hiệu chỉnh phối cảnh loại bỏ hiệu ứng thang hình (keystone) xảy ra khi ống kính không chỉ vuông góc với cảnh vật -- biến dạng hình thang biến một hình chữ nhật đã biết trong thế giới thực thành một vùng màu (blob) không phải hình chữ nhật trong ảnh. Cả hai hiệu chỉnh đều loại bỏ, sau khi chụp xong, các hiệu ứng có nguồn gốc quang học.

5.22.1. Méo xuyên tâm của ống kính

Tài liệu hiệu ứng ống kính thực mô tả méo barrel mà các ống kính góc rộng giá rẻ gây ra. Các điểm ảnh gần tâm khung hình gần như ở đúng vị trí mà mô hình lỗ kim dự đoán; các điểm ảnh gần cạnh bị đẩy ra ngoài một lượng tăng theo bình phương khoảng cách xuyên tâm từ trục quang học. Một đường thẳng trong cảnh vật chạy gần cạnh khung hình sẽ bị cong rõ ràng trong ảnh chụp, và bất kỳ thuật toán thị giác máy cổ điển nào giả định các đường thẳng vẫn thẳng -- phát hiện góc AprilTag, theo dõi cạnh, điều hướng theo đường -- sẽ cho kết quả sai ở các góc.

lens_corr() loại bỏ méo. Phương thức này chạy ánh xạ nghịch đảo: mỗi điểm ảnh đầu ra được lấy mẫu từ vị trí trong đầu vào mà ống kính sẽ đã đẩy ra khỏi đó, và kết quả là một ảnh thẳng về mặt hình học.

img.lens_corr(strength=1.8)

Tham số strength là cốt lõi của hiệu chỉnh. Đây là một con số duy nhất mô tả mức độ phình của ống kính; giá trị gần 1.0 là hiệu chỉnh nhẹ cho ống kính góc rộng vừa phải, và các giá trị lên đến khoảng 2.0 phù hợp cho ống kính fisheye mạnh. Giá trị mặc định là 1.8 là điểm khởi đầu hợp lý cho các ống kính OpenMV Cam tiêu chuẩn; giá trị phù hợp cho bất kỳ ống kính cụ thể nào là vấn đề thử nghiệm vài lần và quan sát ảnh.

Hai tham số phụ thường ổn với giá trị mặc định. zoom (mặc định 1.0) thu phóng đầu ra -- giá trị lớn hơn một cắt ra ngoài để bù đắp cho cách hiệu chỉnh ống kính đẩy các góc ra xa hơn; giá trị nhỏ hơn giữ nhiều hơn phần cảnh đã hiệu chỉnh nhưng với chi phí là có các điểm ảnh trống ở cạnh ảnh. x_corry_corr dịch chuyển tâm của hiệu chỉnh ra khỏi tâm hình học của ảnh, hữu ích khi ống kính không được căn giữa quang học trên cảm biến (trường hợp bất thường nhưng đáng biết).

Một quy trình điển hình: chụp ảnh, chạy lens_corr() một lần để làm thẳng hình học, sau đó chạy bất cứ thứ gì ứng dụng thực sự cần làm với kết quả.

5.22.2. Hiệu chỉnh xoay 3D

Lớp méo hình học kia là biến dạng phối cảnh xảy ra khi mặt phẳng cảm biến không song song với mặt phẳng cảnh vật. Trường hợp điển hình là một biển báo hoặc biển số xe nhìn từ phía dưới: phần trên của biển ở xa ống kính hơn phần dưới, nên nó chiếu nhỏ hơn, và ảnh chụp hiển thị hình chữ nhật như một hình thang với cạnh trên ngắn hơn cạnh dưới.

Giải pháp là áp dụng xoay 3D cho khung hình đã chụp để tái định hướng ảo mặt phẳng cảm biến song song với mặt phẳng cảnh vật. Phép tính toán giống phép ánh xạ phối cảnh mà phát hiện AprilTag sử dụng để khôi phục tư thế của tag từ bốn góc của nó, chạy ngược lại: cho một góc quay, thao tác ánh xạ mỗi điểm ảnh đầu ra trở lại vị trí đầu vào mà góc quay đó sẽ đến từ đó.

rotation_corr() thực hiện hiệu chỉnh đó:

img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)

Ba tham số xoay tính bằng độ và mô tả các góc quay quanh trục x, y và z của camera ảo tập trung vào ảnh. x_rotation nghiêng camera lên hoặc xuống (hiệu chỉnh tự nhiên cho ảnh chụp ở mặt đất của một bức tường); y_rotation xoay ngang camera sang trái hoặc phải; z_rotation xoay camera quanh trục quang học của nó (hiệu chỉnh tự nhiên cho một giá đỡ bị lệch).

x_translationy_translation di chuyển camera ảo theo chiều ngang mà không xoay nó. zoom (mặc định 1.0) thu phóng đầu ra. fov (mặc định 60.0) mô tả trường nhìn dọc của camera, dùng để tính phép chiếu -- giá trị này nên khớp với ống kính thực tế để giữ hình học nhất quán.

Đối với tổ hợp nghiêng và xoay ngang tùy ý, nhiều góc quay khác không được tổ hợp trong một lần gọi. Thứ tự các thao tác được cố định bên trong quá trình triển khai; ứng dụng chỉ cần cung cấp các góc và kết quả sẽ ra.

5.22.3. Chỉnh thẳng một hình chữ nhật đã biết

Dạng hữu ích phổ biến nhất của rotation_corr() là từ khóa corners=, nhận một danh sách bốn tuple (x, y) mô tả các góc của một hình chữ nhật đã biết trong ảnh đầu vào. Phương thức tính toán bất kỳ xoay 3D nào đã ánh xạ một hình chữ nhật thực sự đến bốn điểm cụ thể đó, áp dụng nghịch đảo của xoay đó cho toàn bộ ảnh, và trả về kết quả trong đó hình chữ nhật đã biết trở thành hình chữ nhật trở lại:

plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)

Cách dùng điển hình chính xác là những gì tên gợi ý: một biển số xe (hoặc bất kỳ đặc trưng hình chữ nhật nào khác) được chụp từ góc xiên. Một giai đoạn thượng nguồn phát hiện biển và báo cáo bốn vị trí góc của nó trong ảnh đã chụp; truyền các góc đó cho rotation_corr() tạo ra một ảnh trong đó biển nằm như một hình chữ nhật thực sự, sẵn sàng cho bất kỳ giai đoạn nhận dạng ký tự hoặc khớp mẫu nào tiếp theo.

Khi dạng bốn góc giải quyết được vấn đề mà ứng dụng đang cố giải quyết, nó hữu ích hơn đáng kể so với dạng sáu tham số. Ứng dụng không cần ước tính bất kỳ góc quay nào; nó chỉ đưa bốn điểm cho phương thức và để phương thức tự tìm ra phần còn lại. Dạng sáu tham số hữu ích khi không có hình chữ nhật nào có thể nhận diện được trong cảnh và góc quay phải được tinh chỉnh thủ công từ kiến thức bên ngoài (chẳng hạn góc gắn kết đã được hiệu chỉnh).