2017-11-13 6 views
1

クラスタバウンディングボックスとそれらの上に線を引く(OpenCVの、Pythonの)私は下の画像の中の文字の周りにいくつかのバウンディングボックスを作成し、このコードで

import csv 
import cv2 
from pytesseract import pytesseract as pt 

pt.run_tesseract('bb.png', 'output', lang=None, boxes=True, config="hocr") 

# To read the coordinates 
boxes = [] 
with open('output.box', 'rt') as f: 
    reader = csv.reader(f, delimiter=' ') 
    for row in reader: 
     if len(row) == 6: 
      boxes.append(row) 

# Draw the bounding box 
img = cv2.imread('bb.png') 
h, w, _ = img.shape 
for b in boxes: 
    img = cv2.rectangle(img, (int(b[1]), h-int(b[2])), (int(b[3]), h-int(b[4])), (0, 255, 0), 2) 

cv2.imshow('output', img) 
cv2.waitKey(0) 

OUTPUT

bb-o1

私はこれを持っています:

bb-o2

プログラムは、境界ボックスのX軸に垂線を描画する必要があります(最初のテキスト領域と3番目のテキスト領域のみ)。途中の人はプロセスに興味を持ってはいけません)。

目標はこれです(これを達成する別の方法があります、説明してください):この2つの領域をカバーするマスクを使用して、この2つの線(または、より良い座標群)を取得します。

bb-o3

それは可能ですか?

ソース画像:要求されたとして

src

CSV: プリント(箱)

[['l', '56', '328', '63', '365', '0'], ['i', '69', '328', '76', '365', '0'], ['n', '81', '328', '104', '354', '0'], ['e', '108', '328', '130', '354', '0'], ['1', '147', '328', '161', '362', '0'], ['m', '102', '193', '151', '227', '0'], ['i', '158', '193', '167', '242', '0'], ['d', '173', '192', '204', '242', '0'], ['d', '209', '192', '240', '242', '0'], ['l', '247', '193', '256', '242', '0'], ['e', '262', '192', '292', '227', '0'], ['t', '310', '192', '331', '235', '0'], ['e', '334', '192', '364', '227', '0'], ['x', '367', '193', '398', '227', '0'], ['t', '399', '192', '420', '235', '0'], ['-', '440', '209', '458', '216', '0'], ['n', '481', '193', '511', '227', '0'], ['o', '516', '192', '548', '227', '0'], ['n', '553', '193', '583', '227', '0'], ['t', '602', '192', '623', '235', '0'], ['o', '626', '192', '658', '227', '0'], ['t', '676', '192', '697', '235', '0'], ['o', '700', '192', '732', '227', '0'], ['u', '737', '192', '767', '227', '0'], ['c', '772', '192', '802', '227', '0'], ['h', '806', '193', '836', '242', '0'], ['l', '597', '49', '604', '86', '0'], ['i', '610', '49', '617', '86', '0'], ['n', '622', '49', '645', '75', '0'], ['e', '649', '49', '671', '75', '0'], ['2', '686', '49', '710', '83', '0']] 

はEDIT:

zindarod答えを使用するには、tesserocrを必要としています。 pip install tesserocrからインストールすると、さまざまなエラーが発生する可能性があります。 ホイールのバージョンが見つかりました(時間をかけてインストールしてエラーを解決しようとしましたが、答えの下のコメントを参照してください...):here you can find/download it。このことができます

ホープ..

+0

境界ボックスをクラスタ化して、1行目のクラスタでmax yを取得し、次に2行目のクラスタでmin yを取得し、2 yとすべての幅を使用して矩形を作成することをお勧めしますマスクを持っている。 – api55

+0

それは正しいようです。あなたはそれをする方法を知っていますか?また、私はこの研究のための別のキーワード、「Connected-component labeling」を見つけました。 – Link

+0

接続されたコンポーネントは動作しません。すべてが何らかの形で接続されている場合は、これが機能します。しかし、y値とk = 3のk-meansを使うことができます。次に、y値に応じて3つの文字クラスターを作成します。 kmeansはopencvで実装されています – api55

答えて

3

グーグルたTesseract-OCRは、すでにpage segmentation method(psm)でこの機能を備えています。より良いpythonラッパーを使用するだけで、より多くのtesseractの機能が公開されます。pytesseractよりも機能します。より良いものの1つはtesserocrです。あなたのイメージと

簡単な例:

import cv2 
    import numpy as np 
    import tesserocr as tr 
    from PIL import Image 

    cv_img = cv2.imread('text.png', cv2.IMREAD_UNCHANGED) 

    # since tesserocr accepts PIL images, converting opencv image to pil 
    pil_img = Image.fromarray(cv2.cvtColor(cv_img,cv2.COLOR_BGR2RGB)) 

    #initialize api 
    api = tr.PyTessBaseAPI() 
    try: 
    # set pil image for ocr 
    api.SetImage(pil_img) 
    # Google tesseract-ocr has a page segmentation methos(psm) option for specifying ocr types 
    # psm values can be: block of text, single text line, single word, single character etc. 
    # api.GetComponentImages method exposes this functionality 
    # function returns: 
    # image (:class:`PIL.Image`): Image object. 
    # bounding box (dict): dict with x, y, w, h keys. 
    # block id (int): textline block id (if blockids is ``True``). ``None`` otherwise. 
    # paragraph id (int): textline paragraph id within its block (if paraids is True). 
    # ``None`` otherwise. 
    boxes = api.GetComponentImages(tr.RIL.TEXTLINE,True) 
    # get text 
    text = api.GetUTF8Text() 
    # iterate over returned list, draw rectangles 
    for (im,box,_,_) in boxes: 
     x,y,w,h = box['x'],box['y'],box['w'],box['h'] 
     cv2.rectangle(cv_img, (x,y), (x+w,y+h), color=(0,0,255)) 
    finally: 
    api.End() 

    cv2.imshow('output', cv_img) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows() 

result

+1

...真ん中の2が何を意味するのか分からないが、tesserocrをインストールしようとしているとき、それは私にエラーを与えます。実際には、pyocrもラッパーとして使用しています。これではできませんか?おかげさまで api55 OpenCVの@ – api55

+0

うんを提案されたものよりもさらに良く見える – Link

+0

はすでにGoogleの上に構築*テキスト*モジュールを持っている... 'のpython setup.py egg_info」解決のために1'..Searchingエラーコードで失敗しました:私は今、何をしたいかについて知事が.. エラー思えますtesseract-ocr、残念ながら、Python APIは* psm *機能を公開していません。 – zindarod

0

私は何か他のものを探して、後半にここにいます。私はテッサー・ラッパーを使ったことは一度もありません。彼らがやっているのは、サブプロセスへの呼び出しを抽象化しているだけですか?

これは、サブプロセスに渡されるargsによってpsm設定にアクセスする方法です。 oem、pdf、hocrの各パラメータは完全性のためだけに入れましたが、これは必須ではありません。psmパラメータを渡すことができます。 13 psmのオプションと4つのoemがあるので、端末でヘルプコールを行います。あなたが何をしているかによって、品質はpsmに大きく依存する可能性があります。

subprocess.Popen()を使用してパイプイン/アウトすることも、同じ方法でasyncio.create_subprocess_exec()を非同期的に行うこともできます。

import subprocess 

# args 
# 'tesseract' - the executable name 
# path to the image file 
# output file name - no extension tesser will add .txt .pdf .hocr etc etc 
# optional params 
# -psm x to set the page segmentation mode see more with tesseract --help-psm at the cli 
# -oem x to set ocr engine mode see more with tesseract --help-osm 
# can add a mode parameter to the end of the args list to get output in : 
# searchable pdf - just add a parameter 'pdf' as below 
# hOCR output (html) - just add 'hocr' as below 

args = ['tesseract', 'Im1.tiff', 'Im1', '-psm 1', '-oem 2'] 

# args = ['tesseract', 'Im1.tiff', 'Im1', '-psm 1', '-oem 2', 'pdf'] 
# args = ['tesseract', 'Im1.tiff', 'Im1', '-psm 1', '-oem 2', 'hocr'] 

try: 
    proc = subprocess.check_call(args) 
    print('subprocess retcode {r}'.format(r=proc)) 
except subprocess.CalledProcessError as exp: 
    print('subprocess.CalledProcessError : ', exp) 
関連する問題