5.28. Mã QR và AprilTag¶
Các bộ phát hiện đã đề cập -- vùng màu (blob), đường thẳng, hình tròn, hình chữ nhật -- tìm các đặc trưng hình học: vị trí và đường viền mà một bước tiếp theo sẽ diễn giải. Các bộ phát hiện còn lại tìm kiếm các đặc trưng ký hiệu: các mẫu in có cấu trúc hình ảnh được thiết kế đặc biệt để mã hóa một tải trọng. Camera xác định vị trí chúng, bộ giải mã đọc các bit, và kết quả trả về không phải là một vị trí mà là một chuỗi ký tự (hoặc một ID) mà người in ký hiệu đó đã chọn có chủ ý.
Hai họ ký hiệu này thống trị các ứng dụng camera nhỏ. Mã QR mang văn bản tùy ý, URL, thẻ liên lạc, hoặc tải trọng nhị phân -- các mã 2D hướng đến người tiêu dùng xuất hiện trên áp phích, bao bì và thẻ lên máy bay. AprilTag mang một ID số từ một tập cố định nhỏ, giải mã nhanh ngay cả từ khoảng cách xa, và (khi được cung cấp các thông số nội tại của ống kính) báo cáo một tư thế 6-DoF trong khung hình camera -- các mã 2D hướng đến robot học dùng để đánh dấu máy bay không người lái, mục tiêu hiệu chỉnh và điểm tham chiếu. Cả hai bộ phát hiện đều trả về các đối tượng kết quả với cùng từ vựng hộp giới hạn mà bộ phát hiện blob và rect sử dụng, nhưng tải trọng khiến chúng thực sự khác biệt so với bất kỳ thứ gì đã đề cập đến lúc này.
5.28.1. Mã QR¶
find_qrcodes() quét khung hình để tìm mã QR và trả về danh sách các đối tượng kết quả QRCode:
codes = img.find_qrcodes()
for c in codes:
img.draw_rectangle(c.rect, color=(0, 255, 0))
for corner in c.corners:
img.draw_circle((corner[0], corner[1], 4),
color=(0, 255, 0))
print(c.payload)
Bộ phát hiện nhận một tham số roi tùy chọn duy nhất để giới hạn phạm vi tìm kiếm. Nó cần đầu vào là thang xám -- khung hình màu sắc sẽ được chuyển đổi nội bộ trước khi giải mã.
Mỗi lần phát hiện mang theo hộp giới hạn (x, y, w, h, rect), bốn góc được phát hiện (corners, tứ giác chiếu xạ mà các mẫu tìm kiếm của mã QR tạo ra), và tải trọng được giải mã dưới dạng chuỗi. Các góc là thứ phù hợp để vẽ khi chú thích kết quả phát hiện -- một mã QR nhìn nghiêng góc không được căn chỉnh theo trục và hộp giới hạn chỉ cho một đường viền rộng.
Siêu dữ liệu của bộ giải mã bao gồm mọi thứ mà bộ giải mã QR học được trong quá trình. version là phiên bản mã QR, từ 1 đến 40, quy định kích thước lưới mô-đun (mã phiên bản 1 rộng 21 mô-đun, mã phiên bản 40 rộng 177). ecc_level là mức sửa lỗi (0 đến 3 tương ứng L / M / Q / H); các mức cao hơn dành nhiều từ mã hơn cho việc sửa lỗi và chịu được nhiều hư hỏng hơn nhưng phải trả giá bằng dung lượng tải trọng nhỏ hơn. mask là mẫu mặt nạ (0 đến 7) mà bộ mã hóa chọn để giảm thiểu nhầm lẫn cho bộ giải mã. data_type là kiểu mã hóa mà bộ giải mã báo cáo -- số, chữ-số, nhị phân, hoặc Kanji -- và các cờ is_numeric / is_alphanumeric / is_binary / is_kanji biểu diễn cùng giá trị dưới dạng boolean thân thiện hơn.
eci là giá trị Extended Channel Interpretation, xác định mã hóa văn bản của các byte (UTF-8, ISO-8859-1, v.v.). Một mã QR từ vật liệu in tùy ý có thể không đảm bảo là UTF-8; một ứng dụng cần giải mã các byte chính xác sẽ kiểm tra eci và giải mã theo đó. Đặc biệt với trường hợp Kanji: MicroPython không phân tích cú pháp mã hóa Kanji, vì vậy tải trọng is_kanji phải được xử lý như một mảng byte và được ứng dụng tự giải mã.
Một trường hợp sử dụng điển hình: camera đọc mã QR từ băng chuyền và báo cáo tải trọng đã giải mã cho máy chủ. Camera chạy find_qrcodes() một lần mỗi khung hình, lặp qua danh sách trả về, chọn các mã có data_type phù hợp với mong đợi của ứng dụng, và chuyển tiếp c.payload qua UART hoặc USB. Dữ liệu hộp giới hạn và góc hữu ích cho bản xem trước IDE nhưng không phải điều máy chủ quan tâm.
5.28.2. AprilTag¶
find_apriltags() quét khung hình để tìm AprilTag và trả về danh sách các đối tượng kết quả AprilTag:
tags = img.find_apriltags(families=image.TAG36H11)
for t in tags:
img.draw_rectangle(t.rect, color=(0, 255, 0))
img.draw_cross(t.cx, t.cy, color=(0, 255, 0))
print(t.id, t.decision_margin)
AprilTag khác với mã QR ở mục tiêu thiết kế. Mã QR được xây dựng để mã hóa dữ liệu tùy ý trong một ký hiệu dày đặc duy nhất mà người dùng đọc một lần ở khoảng cách gần. AprilTag được xây dựng để mã hóa một ID nhỏ trong một ký hiệu thưa thớt mà camera đọc liên tục từ xa, với khả năng chịu lỗi tối đa mà mã Hamming của họ ký hiệu cho phép. Sự đánh đổi thể hiện ở cả hai hướng: mã QR có thể mang hàng trăm byte nhưng cần đọc từ gần; AprilTag chỉ mang vài trăm ID duy nhất nhưng đọc đáng tin cậy từ khoảng cách vài mét.
Từ khóa families nhận một bitmask của các họ thẻ cần giải mã. Các họ có sẵn là image.TAG16H5, image.TAG25H9, image.TAG36H10, image.TAG36H11, image.TAGCIRCLE21H7, image.TAGCIRCLE49H12, image.TAGCUSTOM48H12, image.TAGSTANDARD41H12, và image.TAGSTANDARD52H13. Mỗi họ đánh đổi giữa số lượng ID và độ bền. Số H trong tên là khoảng cách Hamming tối thiểu giữa hai mã bất kỳ trong họ -- số bit phải lật trước khi một mã hợp lệ biến thành mã khác -- TAG16H5 có 30 ID ở khoảng cách 5, TAG25H9 có 35 ID ở khoảng cách 9, và TAG36H11 (mặc định và phổ biến nhất) có 587 ID ở khoảng cách 11. Bộ phát hiện sửa tối đa hai lỗi bit bất kể họ nào, vì vậy khoảng cách quyết định mức độ rủi ro của việc sửa đó: một mẫu ngẫu nhiên trong khung hình nhiễu chỉ cần nằm trong vòng hai bit của một mã hợp lệ để giải mã thành phát hiện giả, và các họ có khoảng cách cao hơn trải rộng các mã của chúng thưa hơn nhiều đến mức va chạm như vậy trở nên hiếm -- lý do TAG36H11 là lựa chọn được khuyến nghị. Thời gian phát hiện tỷ lệ với số họ được bật, vì vậy ứng dụng chỉ bật những gì thực sự in ra. Bitmask là OR bit của các hằng số họ khi cần nhiều họ trong một lần gọi.
Mỗi lần phát hiện mang theo từ vựng hộp giới hạn -- x, y, w, h, rect, area, tâm nguyên và tâm dưới điểm ảnh (cx, cy, cxf, cyf) -- và bốn góc được phát hiện (corners). Các trường nhận dạng tiếp theo: id là ID số trong họ (0 đến 586 cho TAG36H11), family là hằng số họ dạng số, và name là tên họ dưới dạng chuỗi.
Các trường chất lượng khớp là những gì ứng dụng dùng để lọc kết quả phát hiện. decision_margin là điểm tin cậy từ 0.0 đến 1.0; cao hơn là tốt hơn, và lọc bỏ các phát hiện dưới decision_margin > 0.1 loại bỏ hầu hết các lần phát hiện giả mà không tốn thêm chi phí. hamming đếm số lỗi bit mà bộ giải mã chấp nhận cho thẻ này -- thấp hơn là tốt hơn, 0 có nghĩa là giải mã hoàn hảo. goodness là một chỉ số chất lượng ảnh lịch sử mà bộ giải mã hiện tại không còn tính nữa; nó luôn là 0.0 và có thể bỏ qua.
5.28.3. Tư thế từ thông số nội tại¶
Tính năng mang tính chuyển đổi của find_apriltags(), tính năng biện minh cho AprilTag như điểm tham chiếu robot học được ưa chuộng, là phương thức có thể phục hồi tư thế 6-DoF của thẻ trong khung hình camera trực tiếp từ các góc được phát hiện và một tập nhỏ các thông số nội tại hiệu chỉnh. Các thông số nội tại là tiêu cự X và Y của camera tính bằng điểm ảnh (fx, fy) và tâm quang học tính bằng điểm ảnh (cx, cy), tất cả bốn giá trị mà ứng dụng đo một lần bằng quy trình hiệu chỉnh và mã hóa cứng sau đó.
Khi các thông số nội tại được cung cấp, AprilTag trả về sẽ điền vào các trường x_translation, y_translation, z_translation với vị trí của thẻ so với camera, và x_rotation, y_rotation, z_rotation (và rotation trùng lặp cho tính đối xứng) với hướng của thẻ. Nếu không có thông số nội tại, cả sáu trường đều là 0.0 và ứng dụng tự chịu trách nhiệm ước lượng tư thế nếu cần.
Các trường dịch chuyển được báo cáo theo đơn vị chiều rộng thẻ: bộ giải mã coi thẻ rộng 1 đơn vị, vì vậy ứng dụng nhân mỗi giá trị dịch chuyển với chiều rộng vật lý của thẻ in ra để có khoảng cách theo đơn vị đo thực. Một thẻ in ở kích thước 100 mm ngang và báo cáo z_translation = 8.3 cách camera 830 mm; cùng thẻ đó in ở kích thước 50 mm ngang ở cùng khoảng cách sẽ báo cáo z_translation = 16.6. Các trường xoay tính bằng radian và không cần tỷ lệ.
Ước lượng tư thế là cơ sở cho nhiều ứng dụng robot học: đưa robot về trạm sạc được đánh dấu bằng thẻ, theo dấu đường điểm tham chiếu được in, phục hồi tư thế của camera từ nhiều thẻ đã biết trong môi trường. Một camera biết thông số nội tại, thấy một thẻ và có vị trí thực tế của thẻ sẽ, qua phép tính tương tự, xác định được vị trí thực tế của chính nó.
5.28.4. Khi nào chọn cái nào¶
Mã QR và AprilTag giải quyết các bài toán khác nhau. Sự lựa chọn giữa chúng phụ thuộc vào những gì ký hiệu in ra mang theo.
Khi ứng dụng cần mang dữ liệu tùy ý qua ký hiệu in -- một URL, một chuỗi số serial, một bản ghi liên lạc -- thì mã QR là lựa chọn đúng đắn. Hàng trăm byte vừa vặn trong một mã có kích thước vừa phải, mã hóa là công khai và được hỗ trợ trên mọi điện thoại thông minh, và bộ giải mã xử lý được xoay, hư hỏng vừa phải và góc nghiêng.
Khi ứng dụng cần một ID nhỏ được đọc liên tục từ xa với tư thế tùy chọn -- một điểm tham chiếu trên robot chuyển động, một mục tiêu hiệu chỉnh trong phòng, một điểm docking trên trạm sạc -- thì AprilTag là lựa chọn đúng đắn. Hàng trăm ID là đủ cho trường hợp sử dụng, mã Hamming phục hồi từ các lỗi bit mà mã QR không thể, và ước lượng tư thế miễn phí khi đã hiệu chỉnh thông số nội tại.
Một số ứng dụng dùng cả hai: AprilTag đánh dấu một vị trí đã biết và một mã QR đi kèm (được in bên cạnh) mang siêu dữ liệu về vị trí đó có nghĩa gì. Hai bộ phát hiện chạy độc lập trên cùng một khung hình và ứng dụng tương quan hộp giới hạn của chúng để khớp mỗi thẻ với mã đồng hành của nó.