4.18. Nhiều cảm biến

Một số OpenMV Cam ghép hai cảm biến ảnh trên cùng một board -- thường là camera màu sắc bên cạnh cảm biến nhiệt FLIR® Lepton®, nhưng hình thức tương tự cũng áp dụng cho các board màu-cộng-sự kiện và bất kỳ phần cứng cảm biến kép nào trong tương lai. Mỗi cảm biến có mảng điểm ảnh riêng, bus điều khiển riêng, và chạy quy trình riêng với tốc độ khung hình riêng. API CSI mở rộng để bao phủ chúng bằng cách cho phép ứng dụng khởi tạo một đối tượng CSI cho mỗi cảm biến vật lý.

4.18.1. Chọn cảm biến nào

Constructor CSI nhận một đối số cid đặt tên cho một cảm biến cụ thể trên board. cid=-1 (mặc định) chọn cảm biến chính; các hằng số cid được đặt tên chọn cảm biến phụ theo chip ID:

import csi

csi_rgb     = csi.CSI()                    # primary colour sensor
csi_thermal = csi.CSI(cid=csi.LEPTON)      # FLIR® Lepton®

Mỗi thể hiện sở hữu cấu hình riêng -- định dạng điểm ảnh, framesize, các nút điều khiển thời gian phơi sáng / độ khuếch đại, pool framebuffer -- và được reset, cấu hình, và đọc độc lập với nhau. Các hằng số cho các cảm biến phụ được hỗ trợ (LEPTON, GENX320, và các hằng số khác được liệt kê trong tài liệu tham chiếu CSI) đặt tên cho chip mà ứng dụng mong đợi trên cổng phụ; driver sẽ thất bại khi xây dựng nếu chip thực tế không khớp.

4.18.2. Chụp từ cả hai cảm biến

Mỗi cảm biến chạy quy trình chụp độc lập với nhau -- cảm biến màu có thể cung cấp ba mươi khung hình mỗi giây trong khi Lepton® cung cấp chín. Cách đơn giản để xử lý sự không khớp đó là để cảm biến nhanh hơn điều khiển vòng lặp và đọc cảm biến chậm hơn theo cách không chặn, lấy bất cứ thứ gì sẵn sàng và bỏ qua lần lặp khi không có gì:

import csi

csi_rgb     = csi.CSI()
csi_thermal = csi.CSI(cid=csi.LEPTON)

csi_rgb.reset()                        # powers the rail, pulses RESET
csi_rgb.pixformat(csi.RGB565)
csi_rgb.framesize(csi.QVGA)

csi_thermal.reset(hard=False)          # I2C reconfigure only
csi_thermal.pixformat(csi.GRAYSCALE)
csi_thermal.framesize(csi.QQVGA)

while True:
    rgb_img     = csi_rgb.snapshot()                  # blocks for next colour frame
    thermal_img = csi_thermal.snapshot(blocking=False)  # returns None if not ready
    if thermal_img is not None:
        # process aligned colour + thermal pair
        pass
    else:
        # process colour only on this iteration
        pass

Lệnh snapshot() chặn làm nhịp vòng lặp; lệnh không chặn trả về khung hình nhiệt gần đây nhất khi một khung mới đã đến kể từ lần gọi trước, và None nếu không. Ứng dụng tiếp tục chạy ở tốc độ khung hình của cảm biến màu và nhận được một khung nhiệt bất cứ khi nào Lepton® tạo ra một.

Mẫu ngược lại -- hai snapshot chặn liên tiếp -- cũng hoạt động, nhưng vòng lặp khi đó chạy ở tốc độ chậm hơn trong hai tốc độ của cảm biến, với quy trình của cảm biến nhanh hơn bị đình trệ giữa các lần lặp. Chọn tốc độ nào mà quá trình xử lý downstream của ứng dụng thực sự muốn điều khiển.

4.18.3. Reset trên các đường nguồn chia sẻ

Một số board cảm biến kép chạy cả hai chip từ một đường nguồn duy nhất hoặc chia sẻ một đường reset. Trên những board đó, reset() đầu tiên đưa đường nguồn lên và xung tín hiệu chia sẻ; các reset tiếp theo trên các thể hiện CSI khác nên truyền hard=False để chúng chỉ lập trình lại chip riêng mà không kéo hàng xóm qua một lần reset:

csi_rgb.reset()                        # primary -- powers the rail, pulses RESET
csi_thermal.reset(hard=False)          # secondary -- I2C reconfigure only

Một hard=True trên cảm biến phụ trong hình thức này sẽ reset lại cảm biến chính như tác dụng phụ, hoàn tác bất kỳ thiết lập nào mà ứng dụng đã đẩy. Trang tài liệu tham chiếu cho mỗi board cảm biến kép ghi chú liệu các đường nguồn có được chia sẻ hay không.

4.18.4. Chọn nguồn luồng

Camera có hai cảm biến có hai thể hiện CSI nhưng vẫn chỉ có một framebuffer luồng giữa chúng. Một đối số constructor chọn cảm biến nào cung cấp khung hình cho xem trước:

csi_rgb     = csi.CSI()                    # primary
csi_thermal = csi.CSI(cid=csi.LEPTON,
                      stream=True)         # preview source

stream=True đặt thể hiện được đặt tên làm nguồn. Khi không có đối số stream= nào, cảm biến chính (cid=-1, mặc định) là nguồn; các thể hiện được xây dựng với cid= của cảm biến phụ giữ im lặng trên xem trước trừ khi stream=True được truyền rõ ràng. Các lời gọi snapshot() trên cảm biến không được chọn vẫn chụp khung hình vào framebuffer của cảm biến đó một cách bình thường -- chúng chỉ không cập nhật xem trước.