本篇主要是紀錄 camera 模組的初始化函式的改寫, 本系列之前的文章參考 :
在前兩篇的測試中所使用的初始化函式寫法其實有 bug, 原寫法如下 :
import time, camera
from machine import reset
def init_camera(**config): # 初始化鏡頭
camera.init(
0, d0=4, d1=5, d2=18, d3=19, d4=36, d5=39, d6=34, d7=35,
href=23, vsync=25, reset=-1, sioc=27, siod=26, xclk=21,
pclk=22, fb_location=camera.PSRAM, format=camera.JPEG,
xclk_freq=camera.XCLK_10MHz, framesize=camera.FRAME_QVGA,
**config)
def capture_image(file_name='capture.jpg'): # 拍攝照片並存檔
time.sleep(2) # 等待攝像頭穩定
buf=camera.capture()
if buf:
with open(f'/{file_name}', 'wb') as f:
f.write(buf)
print(f'Image has been saved as {file_name}')
else:
print('Failed to capture image')
camera.deinit()
del buf
其中 init_camera() 函式的傳入參數使用可變長度參數 **config, 原意是想如果要更改這些參數的預設值 (例如解析度預設是 QVGA 想改為 VGA), 就在呼叫 init_camera() 時傳給 **config, 例如 :
init_camera(framesize=camera.FRAME_VGA)
關於關鍵字參數 **kwargs 用法參考 :
但這樣會出現參數重複的錯誤 (extra keyword arguments given) :
>>> init_camera(framesize=camera.FRAME_VGA)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in init_camera
TypeError: extra keyword arguments given
實踐原意的正確做法應該是要用字典的 setefault() 函式來設定傳入之關鍵字參數 :
import time, camera
from machine import reset
def init_camera(**config): # 初始化鏡頭
config.setdefault('fb_location', camera.PSRAM)
config.setdefault('format', camera.JPEG)
config.setdefault('xclk_freq', camera.XCLK_10MHz)
config.setdefault('framesize', camera.FRAME_QVGA)
camera.init(
0, d0=4, d1=5, d2=18, d3=19, d4=36, d5=39, d6=34, d7=35,
href=23, vsync=25, reset=-1, sioc=27, siod=26, xclk=21,
pclk=22, **config)
def capture_image(file_name='capture.jpg'): # 拍攝照片並存檔
time.sleep(2) # 等待攝像頭穩定
buf=camera.capture()
if buf:
with open(f'/{file_name}', 'wb') as f:
f.write(buf)
print(f'Image has been saved as {file_name}')
else:
print('Failed to capture image')
camera.deinit()
del buf
其實這四個用 setdefault() 設定初始值的參數通常只有 xclk_freq 與 framesize 會需要設定.
測試結果如下 :
不傳入參數的話預設解析度是 320*240 :
>>> init_camera()
0
4
10000000
5
True
>>> capture_image()
8872
Image has been saved as capture.jpg
True
可見呼叫 dict 的 setdefault() 時會傳回設定值.
如果傳入 framesize 參數指定 VGA, 則解析度變成 640*480 :
>>> init_camera(framesize=camera.FRAME_VGA)
0
4
10000000
8
True
>>> capture_image()
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-VSYNC-OVF
cam_hal: EV-EOF-OVF
cam_hal: EV-VSYNC-OVF
cam_hal: EV-EOF-OVF
21140
Image has been saved as capture.jpg
True
下面範例是同時設定 framesize=VGA 與 xclk_freq=20mM 參數 :
>>> init_camera(framesize=camera.FRAME_VGA, xclk_freq=camera.XCLK_20MHz)
0
4
20000000
8
True
>>> capture_image()
cam_hal: EV-EOF-OVF
16460
Image has been saved as capture.jpg
True
結果頻率高檔案大小比較小, 這可能是因為時脈越高, 影像數據擷取速率快, 引入較多信號噪音, 提高了演算法的壓縮比所致.
沒有留言 :
張貼留言