AmazonでJPEGエンコーダ付きのカメラ0.3MピクセルシリアルJPEGカメラモジュールが2000円で売っていたので,まずは動作を確認.
詳細情報はメーカーのWebサイトを参照するとわかる.
UART経由でコマンドやりとりして写真データを取り込むことができるみたい.OmniVisonの(やや)面倒なレジスタを叩かなくていいのは手軽で嬉しい.
撮れる画像
取得時間
画像取得にかかった時間の計測結果はこんな感じ.
画像サイズ | 時間 | ファイルサイズ |
---|---|---|
640x480 | 10.0秒 | 60KB |
320x240 | 3.42秒 | 18KB |
160x120 | 1.21秒 | 6.8KB |
転送速度がデフォルト(かつ最大)の115200bpsで使っているので,640x480の画像サイズを割ってみると4.2秒くらいは覚悟する必要がある.としても結構かかっているなあ.JPEGなので,圧縮がかかる画像ではファイルサイズはもっと小さく,取得時間も短くなるけど.
次は
ラズパイ+ラズパイカメラでお手軽に写真撮影できるので,Python使える環境でこのカメラをわざわざ使うということは,あまり考えられない.ESP-WROOM-02とかと組み合わせてみようかな,とか思っています.
動作確認用のコード
UARTはPyserial経由のPythonでアクセスするのが便利.というわけでこんな感じのコードを.
camera_reader.py
import sys
import time
import serial
class CameraReader:
def __init__(self, dev):
#self.ser = serial.Serial(dev, timeout=1, baudrate=115200)
self.ser = serial.Serial(dev, timeout=1, baudrate=115200)
def snapshot(self, mode):
if mode < 1:
mode = 1
elif mode > 3:
mode = 3
d = bytes([0x55, 0x48, 0x00, 0x30+mode, 0x00, 0x02, 0x23])
self.ser.write(d)
s = self.ser.read(4)
s = self.ser.read(10)
data_length = (s[6] << 24) + (s[5] << 16) + (s[4] << 8) + s[3]
packages = (s[8] << 8) + s[7]
return data_length, packages
def read_image(self, data_length, packages):
d = b''
for i in range(packages):
cmd = bytes([0x55, 0x45, 0x00, ((i+1) & 0xFF), ((i+1) >> 8) & 0xFF, 0x23])
self.ser.write(cmd)
s = self.ser.read(4) # ack
self.ser.read(3) # 'UF<ID>'
self.ser.read(2) # package id
s = self.ser.read(2) # len
len = (s[1] << 8) + s[0]
s = self.ser.read(len)
d += s
s = self.ser.read(2) # crc
return d
def close(self):
self.ser.close()
if __name__ == '__main__':
args = sys.argv
if len(args) < 3:
print("usage: {0} device output".format(args[0]))
exit(0)
mode = 3
if len(args) > 3:
mode = int(args[3])
reader = CameraReader(args[1])
start = time.time()
a,b = reader.snapshot(mode)
d = reader.read_image(a,b)
elapsed_time = time.time() - start
with open(args[2], "wb") as fout:
fout.write(d)
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")