OpenCVとZBarを使ってPythonでバーコードリーダを作る

PythonからOpenCV 2.2を使う(MacOSX SnowLeopard + homebrew) - 脳みそHackの続きで、ZBar bar code readerと組み合わせてバーコードリーダを作る。

環境

ZBarのインストール

homebrewを用いてZBarをインストールする.

brew install zbar

その後,ZBarのpythonラッパーをpipを用いてインストールする.コンパイルにPIL(Python Image Library)を使用するので、先にPILをインストールする必要がある。

pip install PIL
pip install zbar

また、ZBarの実行にはnumpyも必要なので、numpyもインストールする。
しかし、pipやeasy_installでnumpyをインストールしてZBarを使ったコードを実行しようとすると、

RuntimeError: module compiled against ABI version 2000000 but this version of numpy is 1000009
Traceback (most recent call last):
  File "cv_gray.py", line 1, in <module>
    import cv
ImportError: numpy.core.multiarray failed to import

というエラーメッセージが出てしまう。pipやeasy_installで入るnumpyのバージョンは1.6.0だが、どうやら、ZBarはnumpy2.0.0を使いたいらしい...。
MacOSX SnowLeopard用のnumpy2.0.0インストーラがなかなか見つからない中、http://stronginference.com/scipy-superpack/を見つけたので、インストールしてみる。実行...うまくいった!

virtualenv

virtualenv使ってる人は、共通のsite-packagesから仮想環境のsite-packagesにnumpy-2.0.0.dev_f72c605_20110113-py2.6-macosx-10.6-universal.eggをコピーして、仮想環境上で、

easy_install numpy

という手順を踏むと、仮想環境上でnumpy2.0.0が使えるようになります。
もっとスマートな解決法があれば誰か教えてください。

webカメラで取得した画像中のバーコードをデコードする

Hello Absurd World! Webカメラを使ったバーコードスキャン on pythonを参考に作った。

import cv
import time
import zbar
import Image

cv.namedWindow("camera", 1)
capture = cv.CreateCameraCapture(0)

width = None
height = None

if width is None:
    width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH))
else:
	cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_WIDTH,width)    

if height is None:
	height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT))
else:
	cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_HEIGHT,height) 

while True:
    img = cv.QueryFrame(capture)
    size = cv.GetSize(img)
    gray_img = cv.CreateImage(size, cv.IPL_DEPTH_8U, 1)
    cv.CvtColor(img, gray_img, cv.CV_BGR2GRAY)
    
    scanner = zbar.ImageScanner()
    scanner.parse_config('enable')

    zbar_img = zbar.Image(gray_img.width, gray_img.height, 'Y800', gray_img.tostring())
    scanner.scan(zbar_img)

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

    cv.ShowImage("camera", gray_img)
    k = cv.WaitKey(10);
    if k == 'f':
        break
  1. webカメラから画像を取得する
  2. グレースケールに変換
  3. Zbar.Image形式に変換
  4. 画像をスキャン
  5. デコード結果を表示

という処理をループしている。
ZBarライブラリ内にもvideoの入力を扱う関数が用意されているが、iSight(Macに標準で搭載されているwebカメラ)の指定方法が分からなかった。/dev/にiSightを示すドライバが見当たらないので、iSightは通常のusb接続のwebカメラとは扱い方が異なるようだ。OpenCVではcv.CreateCameraCaptureで引数0をとるとiSightからの画像を取得できる。このあたりよく分かっていないので要勉強。
次は、PythonでAmazon Product Advertising APIを使う - 人工知能に関する断創録を参考にバーコードから書籍情報を取得する。