【OpenCV】cv2.HoughLinesP()の使い方【直線を検出する】

【OpenCV】cv2.HoughLinesP()の使い方【直線を検出する】プログラミング
ゆうすけ
ゆうすけ

OpenCVで画像から直線を検出したいです。

資格マフィア
資格マフィア

cv2.HoughLinesP 関数を使えば良いぞ。
ただ、その前に前処理をしないと上手く直線が検出されない。

 

✔️ 本記事のテーマ

 OpenCVで直線を検出する方法

 

✔️ 読者さんへの前置きメッセージ

本記事は「OpenCV の cv2.HoughLinesP 関数」について書いています。

 

この記事を読むことで
「cv2.HoughLinesP の使い方 や 直線検出に必要な前処理」
について理解できます。

 

OpenCVを使うことで画像中の直線を検出することができます。

 

OpenCVを応用すれば、直線を検出することで、画像から検出した直線を消すこともできます。

 

この記事では、OpenCV を使って、直線を検出する方法を手順ごとに解説します。

 

それでは、解説していきましょう。

OpenCV で直線を検出するサンプルコード

OpenCV で直線を検出するサンプルコード

OpenCV で直線を検出するサンプルコードは以下のようになります。
この記事ではこのサンプルコードに沿って解説していきます。

 

import cv2
import numpy as np


img = cv2.imread("./sample.png")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

reversed_gray = cv2.bitwise_not(gray)

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

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

    line_img = cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 3)

cv2.imwrite("sample_after.png", line_img)

このサンプルコードによって

OpenCVで直線検出を処理する前の画像

↑このような画像から

OpenCVで直線検出を処理した後の画像

↑このような直線(赤線部分)を検出することができます。

 

では、順番に解説していきましょう。

 

OpenCV で直線を検出する手順

OpenCV で直線を検出する手順

OpenCVで画像中から直線を検出する手順は以下の通りです。

  1. 画像の読み込み
  2. 画像のグレースケール化
  3. 画像のビットを反転させる
  4. 画像中から直線を検出する
  5. 検出した直線を書き込む
  6. 画像の書き出し

1~3までは画像から正しく直線を検出するための前処理です。

 

画像処理は前処理が大切で、
この前処理が上手くできていないとOpenCVを使っても綺麗に直線を検出できません。

 

では、直線を検出する方法を手順ごとに解説していきましょう。

 

画像の読み込み

まず、OpenCVで画像処理を行うために対象の画像を読み込みます

 

画像の読み込みにはOpenCV のcv2.imread関数を使います。

 

以下のように、対象の画像パスを引数で指定することで、画像の読み込みを行えます。

img = cv2.imread("./sample.png")

 

なお、OpenCV の cv2.imread関数については
OpenCVで画像を読み込む方法【Python】
の記事で詳しく解説しています。

 

画像のグレースケール化

次に、画像のグレースケール化を行います。

 

画像をグレースケールにすることで後続のcv2.HoughLinesP 関数にインプットすることができます。

 

画像のグレースケール化には OpenCV のcv2.cvtColor関数を使います。

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

直線検出の前処理後画像

 

なお、OpenCV の cv2.cvtColor関数については
OpenCVでグレースケール画像を簡単に作成する【Python】
の記事で詳しく解説しています。

 

画像のビットを反転させる

さらに、グレースケール化した画像をビット反転します。

 

ビット反転させることで、画像の白黒を入れ替えます。

reversed_gray = cv2.bitwise_not(gray)

直線検出のビット反転画像

 

これにより、白が多いカレンダー画像を黒中心にすることで
直線の位置をより明確にすることができます。

 

ちなみに、この手順を飛ばすと次の線分検出で、
直線ではない部分が直線とみなされてしまい、異常な数の直線を検出してしまいます。

 

画像中から直線を検出する

ここまでの前処理が完了したら、直線を検出していきましょう。

 

直線の検出には cv2.HoughLinesP 関数を使用します。

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

 

cv2.HoughLinesP 関数は戻り値として検出した線の座標Ndarray で返します。

[ [x1, y1, x2, y2], [x1, y1, x2, y2], … ]

という値が返ってくるイメージです。

 

また、cv2.HoughLinesP 関数は与える引数が重要になってきます。
それぞれ解説しましょう。

 

cv2.HoughLinesP 関数の第1引数: img

第1引数: img画像データ です。

ここまでで前処理を実施した画像データを渡しましょう。
サンプルコードでは ビット反転画像 reversed_gray を渡しています。

 

cv2.HoughLinesP 関数の第2引数: rho

第2引数: rho直角座標点と直線の距離です。
float 型で指定します。

この引数は少し専門的 & 値を細かに調整する必要がない ので、
デフォルト値で特に問題ないかと思います。

 

cv2.HoughLinesP 関数の第3引数: theta

第3引数: theta直角座標点と直線の角度です。
float 型で指定します。

この引数も第2引数と同じくデフォルト値で特に問題ないかと思います。

 

cv2.HoughLinesP 関数の第4引数: threshold

第4引数: threshold直線とみなすための閾値です。
Int 型で指定します。

直線上にある点の数がこの値以上となった時に直線とみなされます。
今回の画像サイズくらいであれば、100前後を渡しておけばOKです

 

cv2.HoughLinesP 関数の第5引数: minLineLength

第5引数: minLineLength直線とみなす最小の長さです。
Int 型で指定します。

 

この 第5引数 が処理結果の鍵を握っています。

 

単位は px です。
ここで指定した値以上の長さの直線を検出対象とします。

minLineLength を大きく設定しすぎると、取得すべき直線が検出されず、
小さく設定しすぎると、不要な線(文字中の線など)まで取得してしまいます。

 

cv2.HoughLinesP 関数の第6引数: maxLineGap

第6引数: maxLineGap同一直線とみなす点間隔の長さです。

2つの点が1線上にある場合に、
点と点の間の間隔が指定した数値より小さければ、同一の直線として検出します。

 

検出した直線を書き込む

lines には検出した直線の数だけの座標配列が格納されているので、
それらを for 文で回しながら、線分を書き込んでいきます。

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

    line_img = cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 3)
    cv2.imwrite("sample_after.png", line_img)

直線の描画にはcv2.line関数を使用しています。

 

なお、OpenCV の cv2.line関数については
【OpenCV】cv2.line関数の使い方【線分を描画する】
の記事で詳しく解説しています。

 

画像の書き出し

最後に、検出した直線を書き込んだ画像データを画像ファイルとして書き出します。

 

画像データの書き出しにはOpenCV のcv2.imwrite関数を使います。

 

第1引数に画像データ、第2引数に保存先のファイルパスを指定します。

cv2.imwrite("sample_after.png", line_img)

 

なお、OpenCV の のcv2.imwrite関数については
OpenCVで画像を保存する方法【Python】
の記事で詳しく解説しています。

 

画像処理プログラミングを独学で勉強するなら

画像処理プログラミングを独学で勉強するなら

画像から直線を検出する方法について解説しました。

 

OpenCVは画像処理には欠かすことのできないライブラリです。

 

もし、OpenCVについて独学でスキルをつけるなら、以下の書籍がオススメです。

 

この書籍はOpenCVの基礎から応用までを
丁寧にかつ詳細に解説しています。

 

OpenCVのほぼ全てを網羅しているとも言えるほどの徹底ぶりなので、
関数のリファレンスとしても使用することができます。
本記事で解説したcv2.HoughLinesP関数も掲載されています。

エンジニアとしての自身の価値をチェックする(完全無料)

エンジニアとして、

自分の価値がどれくらいのものかご存知でしょうか?

 

エンジニアとしてIT業界に身を置いていると

今の会社でずっと働くのか、フリーランスとして独立するのか …

と様々な選択肢があります。

 

どの選択肢が正解なのかを見極めるためにも、選択肢を広げるためにも

自身の価値を知っておくことはとても重要です。

 

TechClips ME では、

職務経歴書をアップロードするだけで企業からのスカウトを受けることができます。

▼▼▼▼▼

▲▲▲▲▲

しかもTechClips MEでは想定年収を企業から提示してくれるので、

自身の価値を数字で分かりやすくたしかめることができます。

 

登録はもちろん完全無料なので、一度登録してみると良いかもしれません。

 

コメント

タイトルとURLをコピーしました