4.14. Kiến thức cơ bản về CSI¶
Module csi là cách mã Python điều khiển cảm biến camera. Mọi tập lệnh chụp một khung hình đều theo cùng một cấu trúc ba phần: nhập module ở đầu, cấu hình một lần ở giữa, và vòng lặp while True ở cuối liên tục lấy khung hình từ camera từng cái một.
4.14.1. Vòng lặp điển hình¶
import csi, image, time
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
clock = time.clock()
while True:
clock.tick()
img = csi0.snapshot()
# process img here
print(clock.fps())
4.14.2. Mỗi lệnh gọi làm gì¶
import csi, image, timeNhập ba module.
csiđiều khiển cảm biến,imageđịnh nghĩa lớpImagemàsnapshot()trả về, vàtimecung cấp helpertime.clock()dùng để đo số khung hình mỗi giây.csi.CSI()Khởi tạo một thực thể
CSIbao gồm một cảm biến camera vật lý. Constructor này chiếm ngoại vi camera và ghi lại cấu hình theo từng cảm biến. Camera có một cảm biến duy nhất có một thực thểCSI; camera có hai cảm biến (màu cộng nhiệt, màu cộng sự kiện) có hai thực thể, mỗi thực thể được chọn bằng đối sốcidcho constructor.csi0.reset()Cấp nguồn và cấu hình cảm biến. Theo mặc định, nó xung chân (pin) reset của cảm biến, sau đó ghi các thanh ghi I2C của cảm biến về trạng thái khởi đầu đã biết. Các lệnh gọi cấu hình tiếp theo --
pixformat,framesize, các núm điều khiển tự động -- đẩy thêm các lần ghi thanh ghi qua cùng bus điều khiển I2C.csi0.pixformat(csi.RGB565)Ghi các thanh ghi cảm biến để chọn định dạng điểm ảnh đầu ra. Các lựa chọn có sẵn là các định dạng mà trang định dạng điểm ảnh đã giới thiệu:
RGB565,GRAYSCALE,BAYER,YUV422, vàJPEGtrên các cảm biến hỗ trợ nó.csi0.framesize(csi.QVGA)Ghi các thanh ghi chọn độ phân giải đầu ra.
QVGAlà 320 × 240; các kích thước có tên chạy lên đếnWQXGA2(2592 × 1944, khoảng 5 MP) trên các cảm biến hỗ trợ chúng. Tuple(width, height)tùy chỉnh cũng hoạt động, miễn là nó phù hợp với khả năng đầu ra của cảm biến.clock = time.clock()Tạo một helper clock. Mỗi lệnh gọi
clock.tick()bên trong vòng lặp ghi lại thời gian bắt đầu của vòng lặp đó;time.clock.fps()báo cáo tốc độ vòng lặp gần đây theo số khung hình mỗi giây.img = csi0.snapshot()Chụp một khung hình từ cảm biến và trả về nó dưới dạng
Image. Cơ chế cách khung hình đó đi vào bộ nhớ đáng được xem xét kỹ hơn.
4.14.3. Cách snapshot lấp đầy bộ nhớ¶
Cảm biến truyền các điểm ảnh qua bus dữ liệu điểm ảnh được mô tả trong bus cảm biến với tốc độ hàng trăm megabyte mỗi giây -- quá nhanh để CPU sao chép từng điểm ảnh một bằng phần mềm.
Thay vào đó, MCU chuyển giao việc truyền dữ liệu cho Truy cập Bộ nhớ Trực tiếp (DMA) -- một engine phần cứng độc lập với CPU, sao chép các byte từ nơi này sang nơi khác bên trong MCU mà không cần CPU tham gia. Ngoại vi đầu vào camera bắt mỗi byte điểm ảnh vào một FIFO nhỏ trên chip; các giai đoạn ISP chạy ở phía MCU xử lý dữ liệu khi đi qua; và engine DMA ghi các điểm ảnh hoàn chỉnh vào một bộ đệm khung hình trong RAM tại vị trí điểm ảnh tương ứng. Không có gì trong chuỗi đó cần CPU sau khi kênh DMA đã được lập trình.
Khi snapshot() được gọi:
Driver CSI lập trình engine DMA với địa chỉ của bộ đệm khung hình, độ dài truyền (một khung hình đáng điểm ảnh), và một hàm gọi lại cho ngắt DMA-done.
Driver kích hoạt ngoại vi đầu vào camera và chờ cảm biến báo hiệu bắt đầu khung hình tiếp theo.
Khi cảm biến truyền khung hình ra, ngoại vi đưa mỗi byte điểm ảnh qua ISP và đến engine DMA, engine này ghi kết quả vào RAM tại vị trí bộ đệm khung hình tiếp theo. CPU được tự do chạy mã khác trong quá trình truyền.
Khi điểm ảnh cuối cùng của khung hình đến, DMA kích hoạt ngắt done, driver bọc bộ đệm khung hình trong
Image, vàsnapshot()trả nó về cho mã người dùng.
Image được trả về không sở hữu bản sao dữ liệu điểm ảnh -- nó trỏ vào một trong các bộ đệm khung hình của camera trong RAM. Số lượng bộ đệm khung hình mà camera giữ, và cách chúng được chuyển giữa DMA và mã người dùng trong mỗi lần gọi snapshot(), phụ thuộc vào chế độ đệm mà ứng dụng đã chọn qua framebuffers().