ISBN バーコード解析(作りかけ)



携帯で、書籍についているバーコード(ISBN)の写真を撮り、
メールに添付して送ったらその書籍の情報を管理してくれる。
・・・なんておもしろいかもと思い Python でバーコード解析を
行うプログラムを書こうとしていたのですが、


・・・最近の携帯って、バーコード読み取る機能があるんですね。


まあ、よくよく考えるとQRコードが読めるんだから、二次元
バーコードを読むのは簡単なわけで。。。

私の使っている携帯が、カメラが付き始めたころの機種で、
こんな機能もなく、また解像度も激低なので、使い物に
なりそうにありませんでした。

そんなわけで、途中で投げ出した書きかけのソースを
そのうち使うこともあるかもしれないのでメモ


#! /usr/bin/env python
# -*- coding: utf-8 -*-
#バードード画像解析プログラム
#参考URL
#http://kansai.anesth.or.jp/gijutu/python/man-gui/man-pil/man-scripts/man-scripts.php
#http://www.uraken.net/zatsugaku/zatsugaku_109.html
#http://www3.ocn.ne.jp/~fukiyo/math-osy/isbn-2.htm

import Image
import math

def guess_left(bars,bw):

        l_odd = {'3211':0, '2221':1, '2122':2, '1411':3, '1132':4, '1231':5, '1114':6, '1312':7, '1213':8, '3112':9}
        l_even = {'1123':0, '1222':1, '2212':2, '1141':3, '2311':4, '1321':5, '4111':6, '2131':7, '3121':8, '2113':9}
        

        bw_temp = float(bw)
        try_count = 0
        line = ''
        
        while(True):
                line = ''
                line_total = 0
        
                for j in range(len(bar_cache)):
                        bar_w = int(math.ceil(float(bar_cache[j]) / bw_temp))
                        if bar_w > 3:
                                bar_w = 3
                        line += str(bar_w)
                        line_total += bar_w
                        
                #数値の合計が7になるよう、バーコード幅を変化させる
                if line_total == 7:
                        break
                elif line_total > 7:
                        bw_temp *= 1.1
                else:
                        bw_temp *= 0.9
                        
                if try_count > 5:
                        break
                
                try_count += 1
        
        if l_odd.has_key(line):
                print l_odd[line]
        else:
                if l_even.has_key(line):
                        print l_even[line]
                else:
                        print 'no key'
        
        return line
        

def guess_right(bars, bw):
        
        r_odd = {'3211':0, '2221':1, '2122':2, '1411':3, '1132':4, '1231':5, '1114':6, '1312':7, '1213':8, '3112':9}

        
        total = 0
        
        for v in bars:
                total += v
        
        print total
        
        v_t = 0
        line = ""
        
        #面積の比率からバーコード幅を推測する
        for v in bars:
                g_v = int(round( float(v * 7) / float(total) ))
                
                if g_v <= 0:
                        g_v = 1
                elif g_v > 4:
                        g_v = 4
                
                v_t += g_v
                line += str(g_v)
                
        while(v_t > 7):
                if v_t == 8:
                        lt = ''
                        for s in line:
                                if int(s) == 4:
                                        s = '3'
                                lt += s
                                
                        line = lt
                        v_t -= 1
                elif v_t >= 9:
                        lt = ''
                        for s in line:
                                if int(s) >= 3:
                                        s = str(int(s) - 1)
                                lt += s
                                
                        line = lt
                        v_t -= 2
                
        
                
                
        if r_odd.has_key(line):
                print r_odd[line]
        else:
                print 'no key'
        
        return line

if __name__ == '__main__':
        img = Image.open("sample/1.jpg")
        #幅
        print img.size[0]
        #高さ
        #height = img.size[1] / 2
        height = 200
        mono_max = 0
        mono_min = 255
        mono_cache = []
        mono_avg = 0
        
        for i in range(img.size[0]):
                rgb = img.getpixel((i,height))
                mono = (rgb[2] + rgb[1] + rgb[0])/3
                
                if mono_max < mono:
                        mono_max = mono
                        
                if mono < mono_min:
                        mono_min = mono
                        
                #拡大してみる
                if i != 0:
                        mono_cache.append((mono + mono_cache[len(mono_cache) - 1]) / 2)
                
                mono_cache.append(mono)
                
        mono_avg = (mono_max + mono_min)/2 + 4
        print mono_avg
        
        bw = 0
        len_check = False
        
        w_len = 0
        b_len = 0
        index = 0
        bar_cache = []
        
        #バーコード幅を取得
        for i in range(len(mono_cache)):
                mono = mono_cache[i]
                
                #guess white
                if mono > mono_avg:
                        if len_check:
                                bw += 1
                        elif (len_check) == False and (bw != 0):
                                index = i
                                break
                        
                #guess black
                else:
                        if (len_check == False) and (bw == 0):
                                len_check = True
                        elif (bw != 0):
                                len_check = False
        
        left_count = 0
        print bw
        #左側の数値を判定
        for i in range(index, len(mono_cache)):
                mono = mono_cache[i]
                
                #guess white
                if mono > mono_avg:
                        print '□',
                        if w_len == 0:
                                if len(bar_cache) > 0:
                                        bar_cache.append(b_len)
                                b_len = 0
                        
                        w_len += 1
                        
                #guess black
                else:
                        print '■',
                        
                        if b_len == 0 and w_len > 0:
                                bar_cache.append(w_len)
                                w_len = 0
                        
                        b_len += 1
                        
                if len(bar_cache) == 4:
                        print bar_cache
                        print guess_left(bar_cache, bw)
                        left_count += 1
                        bar_cache = []
                        
                if left_count >= 6:
                        index = i
                        break
        
        
        #中間バー読み飛ばし
        now_color = '■'
        w_count = 0
        for i in range(index, len(mono_cache)):
                mono = mono_cache[i]
                if mono > mono_avg:
                        if now_color == '■':
                                w_count += 1
                                
                        now_color = '□'
                        
                else:
                        now_color = '■'
                        if w_count >= 3:
                                index = i
                                break


        for i in range(index, len(mono_cache)):
                mono = mono_cache[i]
                
                #guess white
                if mono > mono_avg:
                        print '□',
                        if w_len == 0:
                                bar_cache.append(b_len)
                                b_len = 0
                        
                        w_len += 1
                        
                #guess black
                else:
                        print '■',
                        
                        if b_len == 0 and w_len > 0:
                                if len(bar_cache) > 0:
                                        bar_cache.append(w_len)
                                w_len = 0
                        
                        b_len += 1
                        
                if len(bar_cache) == 4:
                        print bar_cache
                        print guess_right(bar_cache, bw)
                        left_count += 1
                        bar_cache = []
                        
        #img.show()



もどる