6.18. Ảnh và ndarray¶
Lớp Image là bề mặt nhanh cho công việc điểm ảnh gốc của camera: mọi phương thức trên nó đều hoạt động trực tiếp trên bộ đệm khung hình theo định dạng điểm ảnh gốc của camera. numpy là bề mặt số chung cho mọi thứ khác. Hai phương thức kết nối chúng:
image.Image.to_ndarray()-- sao chép các điểm ảnh của một ảnh vào mộtndarray.Hàm tạo
image.Image-- xây dựng một ảnh mới từ mộtndarray.
Kết hợp lại, chúng cho phép ứng dụng chụp một khung hình, chuyển nó sang numpy để thực hiện phép biến đổi tùy chỉnh, rồi đưa kết quả trở lại một ảnh để hiển thị, lưu, hoặc đưa vào phần còn lại của thư viện ảnh.
6.18.1. Ảnh sang ndarray¶
to_ndarray() cấp phát một ndarray mới và sao chép dữ liệu điểm ảnh của ảnh vào đó (theo ánh xạ dtype bên dưới). Nó không bao giờ là một view vào bộ đệm khung hình của ảnh -- mảng numpy luôn sở hữu các byte của chính nó. Chữ ký là to_ndarray(dtype, *, buffer=None), và hình dạng đầu ra phụ thuộc vào định dạng ảnh:
GRAYSCALE -- mảng 2 chiều, hình dạng
(height, width).RGB565 -- mảng 3 chiều, hình dạng
(height, width, 3), các mặt phẳng theo thứ tự R/G/B.
Đối số dtype kiểm soát cách mỗi giá trị điểm ảnh 8-bit v được ánh xạ:
|
phần tử |
ánh xạ cho giá trị điểm ảnh 8-bit |
|---|---|---|
|
|
|
|
|
|
|
|
|
Ví dụ -- xem một khung hình thang xám dưới dạng ma trận uint8
import csi
from ulab import numpy as np
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.QVGA)
img = csi0.snapshot()
a = img.to_ndarray('B') # shape (240, 320), dtype=uint8
print(a.shape, a.dtype)
print("mean brightness:", np.mean(a))
Từ khóa buffer= cho phép ứng dụng tái sử dụng một bytearray đã được cấp phát sẵn, để camera không phải cấp phát một cái mới mỗi khung hình:
buf = bytearray(320 * 240)
while True:
img = csi0.snapshot()
a = img.to_ndarray('B', buffer=buf)
# ... process a ...
6.18.2. ndarray sang ảnh¶
Đi theo chiều ngược lại, truyền ndarray làm đối số đầu tiên cho image.Image. Hàm tạo cấp phát một bộ đệm ảnh mới và sao chép các giá trị của mảng vào đó, cắt giới hạn và làm tròn về 0..255
image.Image(arr, *, buffer=None, copy_to_fb=False)
Hàm tạo suy ra hình học và định dạng điểm ảnh từ hình dạng của mảng:
hình dạng
(h, w)-- ảnhGRAYSCALE.hình dạng
(h, w, 3)-- ảnhRGB565.
ndarray phải có dtype float; hàm tạo hiện chỉ hỗ trợ trường hợp đó. Các giá trị được làm tròn và cắt giới hạn về phạm vi 0..255.
buffer= cho phép ứng dụng cung cấp một bytearray đã được cấp phát sẵn cho ảnh kết quả. copy_to_fb=True ghi kết quả vào bộ đệm khung hình của camera, đây là lựa chọn đúng khi kết quả cần xuất hiện trong bản xem trước của IDE.
6.18.3. Chu trình khép kín¶
import csi
import image
from ulab import numpy as np
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.GRAYSCALE)
csi0.framesize(csi.QVGA)
img = csi0.snapshot()
a = img.to_ndarray('f') # work in float space
a = 255.0 * (a / 255.0) ** 0.5 # gamma correction
out = image.Image(a, copy_to_fb=True) # back to an image
6.18.4. Khi nào nên dùng cầu nối¶
Cầu nối này là câu trả lời đúng khi ứng dụng cần một phép toán số chung mà các phương thức image tích hợp không cung cấp -- bộ lọc tùy chỉnh, pha trộn tùy chỉnh, các phi tuyến bất thường -- hoặc khi dữ liệu điểm ảnh cần kết hợp với dữ liệu không phải ảnh (các trục IMU, mẫu âm thanh) trong một phép tính duy nhất.
Đây không phải là câu trả lời đúng cho việc xử lý điểm ảnh thông lượng cao mà lớp Image đã đảm nhiệm. Các phương thức tích hợp hoạt động trực tiếp trên bộ đệm khung hình theo định dạng điểm ảnh gốc của camera và nhanh hơn nhiều so với biểu thức numpy tương đương. Hãy dùng cầu nối cho những phép toán mà thư viện ảnh chưa cung cấp sẵn.