Python

画像 から 線 取得してみた!【 Python OpenCV 】

k.w

Python + OpenCV を使って、 画像 から 線 取得を試したいと思います。
線取得といっても、いろいろな線がありますが、まずは直線を”HoughLinesP”の使い方の基本をおさえたいと思います。実際には答えがなく、画像にあった微調整が必要になりますが、ライブラリの動きを理解することは必須となります。

縦線・横線の指定はこちらから

[https://way2se.ringtrees.com/py_cv2-002/]

[https://way2se.ringtrees.com/py_cv2-003/]

スポンサーリンク

サンプル画像

どこにでもあるような2次元表をサンプルとして取り上げます。
(サイズ → 横:313px 縦:132px)

使用するライブラリ説明

【HoughLinesP】

lines = cv2.HoughLinesP(img, rho, theta, threshold, minLineLength, maxLineGap)

  • img:取り込む画像。
  • rho:よくわかりませんが、デフォルト 1 で問題なさそう。
  • theta:ランダムに線を判断するための回転角。大きくすれば複雑な線を認識する。
  • threshold:文字などの非線を除外する閾値(の様なもの)
  • minLineLength:連なる点の集合の、最小値。この値以上を線としてみなす。
  • maxLineGap:どれだけ離れている点(線)を一つの線としてみなすか判断。

各引数をふった挙動事例は以下をご覧ください。

[https://way2se.ringtrees.com/py_cv2-004/]

サンプルソース(コード)

/* import設定 */
import os
import configparser as cfg
import glob
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from operator import itemgetter

/* Config設定 */
cfg = cfg.ConfigParser()
cfg.read('config.ini', 'UTF-8')

/* File読み込みフォルダ指定 */
files = glob.glob(cfg.get('Folder', 'img_folder') + '/*.jpg', recursive=True)
print(files)

/* File読み込み(複数可) */
for file in files:
    filename = os.path.basename(file)
    print('File:' + filename)
    img = cv2.imread(file, 0)
    minlength = 10
    gap = 0
    judge_img = cv2.bitwise_not(img)

    lines = []
    lines = cv2.HoughLinesP(judge_img, rho=1, theta=np.pi/360, threshold=100, minLineLength=minlength, maxLineGap=gap) 	 	 	 	 	 	 	 	 	

    line_list = []
    for line in lines:
        whiteline = 3
        lineadd_img = cv2.line(judge_img, (line[0][0], line[0][1]), (line[0][2], line[0][3]), (255, 255, 255), whiteline)
        x1 = line[0][0]
        y1 = line[0][1]
        x2 = line[0][2]
        y2 = line[0][3]
        line = (x1, y1, x2, y2)
        line_list.append(line)

    line_list.sort(key=itemgetter(0, 1, 2, 3))

    line_list = pd.DataFrame(line_list)
    print('line_list_pd')
    print(line_list)
    plt.imshow(lineadd_img)

※コンフィグ設定(11~16行目)については、以下参照ください。

[https://way2se.ringtrees.com/py_cfg-001/]

線を取得するコードは実はたった1行なのです。(32行目)

HoughLinesPで取得した、座標(x1,y1,x2,y2)に対して、同じくOpenCVのlineを使い、直線を描画することになります。(32行目~)

すなわち、HoughLinesPの直線取得制度が、カギとなります。

変数である、各種パラメータ(29行目)を振り、取り扱う画像の特性をうまく理解し調整することが意図通りの結果を出す最短の道です。

 

上記、ソースを実行した際に結果です。
黄色の部分が線として認識している部分です。

意図した取得ではないので、微調整が必要な状態が分かるかと思います。

ぜひ、トライして、各パラメータを振って意図通りに取得できるようになりましょう!

 

 

ABOUT ME
記事URLをコピーしました