2017年07月09日

Python + pyzbar + OpenCVを用いたバーコードSCANによる駿河屋買取価格確認

部屋に本があふれていて処分に悩んでいます。本の売却ということでBOOKOFFに持っていこうか悩んだのですが、BOOKOFFだと買い叩かれると言われているため、あらかじめ値段がWebでわかる駿河屋の買取も試してみようかなと思いました。

ただし、値段を調べるためにはISBNを入力したり本のタイトルを入力しないといけません。少し試してみたのですが、本が多いと検索のための入力が思ったより大変なので、ISBNのバーコードをノートPCのWebカメラで認識させて自動で買取ページを表示させてみようとしました。

以下はその備忘録です。

使用するモジュール

  • OpenCV
  • pyzbar
  • requests
  • BeautifulSoup
今回Python3を用いているので、zbarではなくpyzbarを使用しています。また、各モジュールのインストールコマンドは下記で実施しました。(もしかしたら、あらかじめインストール済みのがあったかもしれませんが、念のため実施しています)
> pip install opencv-python
> pip install pyzbar
> pip install requests
> pip install beautifulsoup4

ソースコード

Webカメラで認識させてカメラで取得した画像をWindowに表示しつつ、ISBNの9784にHITしたら該当する駿河屋のページをブラウザで開くようにしています。また、ESCを叩くと終了します。
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol
import cv2
import re
import requests
import webbrowser, bs4

if __name__=="__main__":
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
cv2.namedWindow("Capture", cv2.WINDOW_AUTOSIZE)

isbnNumber = ""
while True:
ret, image = capture.read()
if ret == False:
continue
# GrayScale
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Show image
cv2.imshow("Capture", image)
# Write imagefile
cv2.imwrite("image.png", image)
# Decoding for barcode(EAN13)
allCodes = decode(image, symbols=[ZBarSymbol.EAN13])

if len(allCodes) > 0: # Barcode was detected
for code in allCodes:
codesStr = str(code)
isbnPattern = r"9784\d+"
isbnSearchOB = re.search(isbnPattern,codesStr)
if isbnSearchOB: # ISBN was detected
if isbnNumber != isbnSearchOB.group(): # New ISBN was detected
isbnNumber = isbnSearchOB.group()
webbrowser.open('http://www.suruga-ya.jp/search_buy?category=&search_word='+ isbnNumber +'&key_flag=1&tab=1')
# Get titles for debug
res = requests.get('http://www.suruga-ya.jp/search_buy?category=&search_word='+ isbnNumber +'&key_flag=1&tab=1')
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, "lxml")
print(isbnSearchOB.group() + ":")
allTitles = soup.select('.title a')
if len(allTitles) == 0:
print ("NOT FOUND")
else:
for title in allTitles:
print (title)

keyInput = cv2.waitKey(33) # 30fps
if keyInput == 27: # when ESC
break

結果

試しに下記をwebカメラでSCANしてみました。

下記のようにブラウザで表示されました。値段がつくものはこのページからカートに入れていけば良いのかなという考え方で作ってみました。

20170709_python_0.jpg

20170709_python_1.jpg

また、CUI上にDebug用に出力している情報は下記となります。
9784532196721:
<a href="/kaitori_detail/3Z106857">&lt;&lt;趣味・雑学&gt;&gt; 問題解決力がみるみる身につく 実践 なぜなぜ分析 / 小倉仁志</a>
9784094516760:
<a href="/kaitori_detail/2M6251">限定7)妹さえいればいい。 ドラマCD付き限定特装版  / 平坂読</a>
<a href="/kaitori_detail/2M6469">限定7)妹さえいればいい。 ドラマCD付き限定特装版  ゲーマーズ限定ダブルカバー付 / 平坂読</a>

バーコードの認識率としては、上手くいくときは連続で認識できるけれど、駄目なときは連続でNGなので、光の加減とかコントラストの調整によって、多少改善できるのかなと思います。

あと、一番重要な駿河屋での買い取り価格ですが、ほとんどが0円でした……。結局BOOKOFFに持っていくことになるのかもしれません。

追記
結局BOOKOFFに売ってきました。買い取りのレシートの長さが……
20170709_python_2.jpg

posted by くまなべ at 20:22 | Comment(0) | TrackBack(0) | Python