Open CVで表からセルを認識してPyQt5のQGraphicsViewに認識結果を表示してみた
2020/10/12 categories:PyQt5| tags:Python|PyQt5|Open CV|
OCR Tool Rev1としてアップデートしました。 2021/4/6
Open CVを使って表が書かれている画像からセルを認識して、PyQt5のQGraphicsViewにセルの領域やセルに含まれる文字列の領域を表示して、QTableViewにセルごとの画像を表示するプログラムを作成しました。
画像を開く
Open filesをクリックしてファイルを選択すると画像を読み込み、テーブルのセルをクリックすると読み込んだ画像が表示されます。
読み込みはQtGui.QPixmapで読み込んでいます。
QtGui.QPixmap(filename)
セルの認識の確認
Recognitionをクリックすると表の認識を実行して認識結果が表示されます。セルとして認識したエリアは赤枠で表示され、右のリストのBackやNextで認識した個所を確認できます。また、リストのアイテムをクリックすることでも認識エリアに赤枠が表示されます。
cv2.imread()で作成したcv2画像からcv2.Canny()でエッジ画像を作成して、cv2.findContours()でエッジ画像から輪郭を抽出して、cv2.approxPolyDP()で輪郭を近似ポリゴンに変換してセルを認識します。セルは四角形なのでcv2.approxPolyDP()で得られたポリゴンの点が4個なら四角形という判定を行っています。四角形の座標x, yと縦横の大きさw, hは下記コードのx, y, w, hの通りです。
cv2_image = cv2.imread( str(filename) )
gray = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY)
edge = cv2.Canny(gray, 1, 100, apertureSize=3)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
edge = cv2.dilate(edge, kernel)
contours, hierarchy = cv2.findContours(edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
approxes = []
for contour, hierarchy in zip(contours, hierarchy[0]):
area = cv2.contourArea(contour)
if not area_range[0] < area < area_range[1]:
continue
approx = cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour, True), True)
if len(approx) == 4:
approxes.append(approx)
rects, crops, crop_images = [], [], []
for approx in approxes:
p1, p3 = approx[0][0], approx[2][0]
x, y = p1[0], p1[1]
w, h = p3[0] - p1[0], p3[1] - p1[1]
rect = [x, y, w, h]
認識内容の確認
Edgeをチェックするとセルの領域認識用に作成したエッジ検出した画像が表示されます。Detect rectをチェックするとセルとして認識したエリアを全て青枠で表示して、Crop rectをチェックするとセル内にある文字を認識したエリアを緑枠で表示します。
セル認識の設定
Recognitionをクリックしてテーブルの認識を行った後にSplit cellsをクリックすると、クロップされた画像がテーブルに表示されます。
セルを分割してテーブルに表示する
Click Recognition to recognize the table, then click Split cells to display the cropped image in the table.
ソースコード
[github] (https://github.com/ymtlab/table_recognition_with_opencv_and_pyqt5/tree/daf1f1df7755046cddd10ab6c7b651dc54dfd36f)にアップロードしました