Amazonで2000円で売ってたJPEGカメラの動作確認


AmazonでJPEGエンコーダ付きのカメラ0.3MピクセルシリアルJPEGカメラモジュールが2000円で売っていたので,まずは動作を確認.
詳細情報はメーカーのWebサイトを参照するとわかる.
UART経由でコマンドやりとりして写真データを取り込むことができるみたい.OmniVisonの(やや)面倒なレジスタを叩かなくていいのは手軽で嬉しい.

撮れる画像

640x480

320x240

160x120

取得時間

画像取得にかかった時間の計測結果はこんな感じ.

画像サイズ 時間 ファイルサイズ
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]")