Help us understand the problem. What is going on with this article?

OpenCVで直線の検出

More than 1 year has passed since last update.

はじめに

OCRで読み込ませる時に、画像の枠線や罫線がノイズとなり、邪魔をして正しく読み込めないときがあります。
ここでは、そのような線を検出し、削除してみたいと思います。
ハフ変換という関数を利用するのですが、ハフ変換ってなんぞや?という感じで、ここでは説明しませんので、ググってください…。

では、やることについて1つずつ説明し、最後にすべてのソースをくっつけてみます。

直線の検出方法

HoughLinesP 関数を使い、白と黒だけの2値画像から検出
下記のステップでやってみます

0.画像の読み込み
1. グレースケールに変換
2. ネガポジ変換で反転
3. ハフ変換でラインの検出
4. 線の色付け

0. 画像の読み込み

  • 対象となる画像です
img = cv2.imread("calendar.png")

calendar.png

1. グレースケールに変換

グレースケールに変換します。

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("calendar_mod.png", gray)

calendar_mod.png

2. ネガポジ変換で反転

この変換で白と黒を逆転させ、白黒はっきりさせます。
こうすることで、線が白く(明るく)なり、特定がしやすくなります。

gray2 = cv2.bitwise_not(gray)
cv2.imwrite("calendar_mod2.png", gray)

calendar_mod2.png

3. ハフ変換でラインの検出

ハフ変換自体難しく、ここでハマりました。
ここでは対象の画像に対して、パラメータ値の調整が必要になります。

  • rho, theta はデフォルトを利用
  • threshold は、直線を動かして、その直線状に乗ってきた点の数がこの値を超えたら線とみなす
  • minLineLength は、ここに指定された値以上の長さを持つ線の候補が見つかったら、それを線として検出する
  • maxLineGapは、2つの点が1つ線上にある場合に、点と点の間の間隔がここに指定した数より小さければ、同一の線とみなす

minLineLengthの値を大きい場合

lines = cv2.HoughLinesP(gray2, rho=1, theta=np.pi/360, threshold=80, minLineLength=400, maxLineGap=5)
print(lines)
  • lineの座標 x1, y1, x2, y2 が7セットだけ返ってきました。
[[[ 11 391 515 391]]
 [[ 11 139 515 139]]
 [[ 11  13 515  13]]
 [[ 11 328 515 328]]
 [[ 11 265 515 265]]
 [[ 11  76 515  76]]
 [[ 11 202 515 202]]]
  • 下図の赤線7本になります。(線の色付けは次項参照)
  • minLineLengthの値が縦線の長さを超えてしまってるため、縦線が検出されていません。

calendar_mod3.png

minLineLengthの値を小さい場合

lines = cv2.HoughLinesP(gray2, rho=1, theta=np.pi/360, threshold=80, minLineLength=30, maxLineGap=5)
  • 今度は文字部分までが線と認識されてしまいました。

calendar_mod3.png

調整の上、今回の画像はこのくらい

lines = cv2.HoughLinesP(gray2, rho=1, theta=np.pi/360, threshold=80, minLineLength=80, maxLineGap=5)

calendar_mod3.png

4. 線の色付け

赤線で線を引く

上記にもあるとおり、線の座標が返ってくるので、色を付けるのがこちらになります。
複数の線座標が取れるので、ループで回して、line関数に設定していきます。
その結果が上記の赤線の図です。

for line in lines:
    x1, y1, x2, y2 = line[0]

    # 赤線を引く
    red_line_img = cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 3)
    cv2.imwrite("calendar_mod3.png", red_line_img)

線を消す

逆に線を消すには、白で線を塗りつぶせば良いのです。

for line in lines:
    x1, y1, x2, y2 = line[0]
    # 線を消す(白で線を引く)
    no_lines_img = cv2.line(img, (x1,y1), (x2,y2), (255,255,255), 3)
    cv2.imwrite("calendar_mod4.png", no_lines_img)

calendar_mod4.png

まとめ

上記のソースをまとめるとこのようになります。

import cv2
import numpy as np

# カレンダー
img = cv2.imread("calendar.png")
img2 = img.copy()
img3 = img.copy()

# グレースケール
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imwrite("calendar_mod.png", gray)

## 反転 ネガポジ変換
gray2 = cv2.bitwise_not(gray)
cv2.imwrite("calendar_mod2.png", gray2)
lines = cv2.HoughLinesP(gray2, rho=1, theta=np.pi/360, threshold=80, minLineLength=80, maxLineGap=5)

for line in lines:
    x1, y1, x2, y2 = line[0]

    # 赤線を引く
    red_lines_img = cv2.line(img2, (x1,y1), (x2,y2), (0,0,255), 3)
    cv2.imwrite("calendar_mod3.png", red_lines_img)

    # 線を消す(白で線を引く)
    no_lines_img = cv2.line(img3, (x1,y1), (x2,y2), (255,255,255), 3)
    cv2.imwrite("calendar_mod4.png", no_lines_img)
tifa2chan
主にアプリ開発をしています。
future
ITを武器とした課題解決型のコンサルティングサービスを提供します
http://future-architect.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした