Raspberry Pi 備忘録 / Mbedもあるよ!

Raspberry Pi であれこれやった事の記録

WEBカメラからQRコードを読み取る

QRコードを用意する

なんでもいいが、 QR Code Editor http://freesoft-100.com/review/qr-code-editor.php を、使わせていただいている。

pythonスクリプトを作る

zbar-0.10/examples/scan_image.py を一部変更して使う。

import zbar
import PIL.Image

file = 'test.jpg'

scanner = zbar.ImageScanner()
scanner.parse_config('enable')

# greyscale L
pil = PIL.Image.open(file).convert('L')
(width, height) = pil.size

# Return image as a bytes object
raw = pil.tobytes()

# The Y800 color format is an 8 bit monochrome format.
image = zbar.Image(width, height, 'Y800', raw)

# scan the image for barcodes
scanner.scan(image)

for symbol in image:
    print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data

del(image)

用意したQRコードの画像を読み込ませてみる。

$ python qr.py test.jpg 
decoded QRCODE symbol "http://pongsuke.hatenablog.com/"

成功したので、引き続き、カメラで撮影したQRコードを読みこませる。
まずは、撮影したjpeg画像を、読み込ませる。

カメラを準備する

LOGICOOL C270 だと、フォーカスが甘いので、Logitech, Inc. QuickCam Orbit/Sphere AF をさして見た。

$ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 008: ID 046d:0994 Logitech, Inc. QuickCam Orbit/Sphere AF
Bus 001 Device 005: ID 0461:4d81 Primax Electronics, Ltd 
Bus 001 Device 006: ID 413c:2107 Dell Computer Corp. 
                     brightness (int)    : min=0 max=255 step=1 default=-8193 value=128
                       contrast (int)    : min=0 max=255 step=1 default=57343 value=32
                     saturation (int)    : min=0 max=255 step=1 default=57343 value=32
 white_balance_temperature_auto (bool)   : default=1 value=1
                           gain (int)    : min=0 max=255 step=1 default=57343 value=112
           power_line_frequency (menu)   : min=0 max=2 default=2 value=2
      white_balance_temperature (int)    : min=0 max=10000 step=10 default=61432 value=3622 flags=inactive
                      sharpness (int)    : min=0 max=255 step=1 default=57343 value=224
         backlight_compensation (int)    : min=0 max=2 step=1 default=57343 value=1
                  exposure_auto (menu)   : min=0 max=3 default=0 value=3
              exposure_absolute (int)    : min=1 max=10000 step=1 default=166 value=152 flags=inactive
         exposure_auto_priority (bool)   : default=0 value=1
                   pan_relative (int)    : min=-4480 max=4480 step=0 default=0 value=0 flags=write-only
                  tilt_relative (int)    : min=-1920 max=1920 step=0 default=0 value=0 flags=write-only
                      pan_reset (button) : flags=write-only
                     tilt_reset (button) : flags=write-only
                          focus (int)    : min=0 max=255 step=1 default=254 value=200
                      led1_mode (menu)   : min=0 max=3 default=31 value=3
                 led1_frequency (int)    : min=0 max=255 step=1 default=0 value=0
       disable_video_processing (bool)   : default=129 value=0
             raw_bits_per_pixel (int)    : min=191 max=31 step=1 default=129 value=0

フォーカス、パンとチルト(首振り)にも対応している。

# v4l2-ctl --set-ctrl focus=200して、フォーカスを近くに合わせて、
# v4l2-ctl --set-ctrl tilt_relative=3000して、下を向けて、 印刷したQRコードを撮影する。

$ fswebcam -d v4l2:/dev/video0 -i 0 -p YUYV test.jpg

f:id:pongsuke:20151224114107j:plain

$ python qr.py test.jpg 
decoded QRCODE symbol "http://pongsuke.hatenablog.com/"

成功したので、次は、カメラに写っている映像を解析して、QRコード情報を読み取る。

まずは、サンプル zbar-0.10/examples/read_one.py から試す。

#!/usr/bin/python
from sys import argv
import zbar

# create a Processor
proc = zbar.Processor()

# configure the Processor
proc.parse_config('enable')

# initialize the Processor
device = '/dev/video0'
if len(argv) > 1:
    device = argv[1]
proc.init(device)

# enable the preview window
proc.visible = True

# read at least one barcode (or until window closed)
proc.process_one()

# hide the preview window
proc.visible = False

# extract results
for symbol in proc.results:
    # do something useful with results
    print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data

ちゃんと読み取れた。

zbar の、process_one()の kill の仕方がわからない・・・。