OpenCVで直線検出・矩形検出はPylsdで十分【Python】

OpenCVで直線検出・矩形検出はPylsdで十分【Python】 プログラミング

この記事で、OpenCVで直線検出・矩形検出する方法を解説しています。
ただし、OpenCVだけには頼りません。
助っ人を用意しています。

その助っ人は、Pylsdです。
Pylsdを利用することで、余計なパラメータ調整とはサヨナラできます。

本記事の内容

  • Pylsdとは?
  • LSDで直線検出・矩形検出する環境
  • LSDで直線検出・矩形検出を行う
  • 【結論】Pylsdを直線検出・矩形検出では使うべき

それでは、上記に沿って解説していきます。

Pylsdとは?

主役となるのは、Pylsdです。
このPylsdでは、LSD (Line Segment Detector)というアルゴリズムを採用しています。

通常OpenCVで直線検出をやろうとすれば、ハフ変換が出てきます。
このハフ変換を使いこなすのは、また大変なのです。

パラメータ調整を画像毎に行う必要があります。
正直、素人では使いこなせません。

LSD

それに対して、LSDではパラメータ調整が不要です。
LSDは素晴らしいと思いませんか?

LSDに興味を持ってもらったところで、簡単に説明を行います。
LSDは、正式にはLine Segment Detectorです。
日本語で言うと、線分検出器となります。

LSDの仕組みを簡単に言うと、明るさによって直線を検出しています。
利用することが目的なので、個人的にはこのぐらいの理解で十分です。

ライセンス問題

「Pylsd、LSD最高!!」のはずですが、実はそんな感じではありません。
「OpenCV 直線検出」をGoogleで検索すると、ハフ変換が出てきます。

「LSDの方が精度はいいけど、Pylsdを利用しない」という声もあります。
これは、どうやらライセンスが原因のようです。

LSDのコード部分は、AGPLです。
そのAGPLのコードを利用している、PylsdもAGPLになるらしいです。

でも、Pylsdの公式サイトではBSDと表記されています。
ここは主眼ではないので、スルーします。

さらに、Pylsdを利用したプログラムもAGPLになるということです。
だから、Pylsdを利用するときは注意しましょうというロジックになるみたいです。
中には、利用しないという人もいます。

なお、AGPLはすべてをさらけ出すというライセンスです。
要望があった場合は。

正直、個人的にはどうでもいいです。
そもそも、Pylsdは閉じた環境で利用します。

商品化・Webサービスとして公開をする場合、ライセンスには注意すべきでしょう。
そうではないなら、何も気にすることはありません。

LSDで直線検出・矩形抽出する環境

以下の2つが必要です。

  • OpenCV
  • Pylsd

OpenCV

OpenCVのインストールは前提です。
次の記事でOpenCVのインストールをまとめています。

なお、この記事ではWindows上のPythonでの環境を前提にしています。

Pylsd

公式サイト
https://pypi.org/project/ocrd-fork-pylsd/

PIPでパッケージをインストール可能です。
インストールは、以下のコマンドとなります。

pip install ocrd-fork-pylsd

インストールが成功したら、実際に動かしてみましょう。

LSDで直線検出・矩形検出を行う

直線検出

この画像を利用します。

sample.jpg

LSDで直線検出元画像

公式に記載されているコードをそのまま利用します。
もちろん、画像パスは変更。

import cv2
import numpy as np
import os
from pylsd.lsd import lsd

fullName = './img/sample.jpg'

folder, imgName = os.path.split(fullName)
src = cv2.imread(fullName, cv2.IMREAD_COLOR)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

lines = lsd(gray)
for i in range(lines.shape[0]):
    pt1 = (int(lines[i, 0]), int(lines[i, 1]))
    pt2 = (int(lines[i, 2]), int(lines[i, 3]))
    width = lines[i, 4]
    cv2.line(src, pt1, pt2, (0, 0, 255), int(np.ceil(width / 2)))
    
cv2.imwrite(os.path.join(folder, 'cv2_' + imgName.split('.')[0] + '.jpg'), src)

実行すると、画像のあるフォルダに以下の画像が出来ています。

cv2_sample.jpg

LSDで直線検出画像

次の1行で直線検出が完了しています。

lines = lsd(gray)

そのための準備も、画像をグレースケール化しているだけです。
ハフ変換と比較すると、圧倒的に簡単です。

矩形検出

次は、矩形(長方形)です。
直線がいければ、矩形検出もできるはず。

sample2.jpg

LSDで矩形検出元画像

上記プログラムでファイルパスだけ変更して、実行。

cv2_sample2.jpg

LSDで矩形検出画像

欲張って影まで検出しています。
でも、かなり優秀です。

パラメータ調整を何もしていません。
それでこの精度です。

【結論】Pylsdを直線検出・矩形検出では使うべき

検証した結果を見てもわかるように、Pylsdを使うべきです。
ライセンスが気になる人は、気になるとは思います。

気になる人は、頑張ってハフ変換で頑張りましょう。
それか、AGPLのもとですべてをさらけ出す覚悟を決めましょう。

ちなみに、MongoDBはAGPLのようです。
とにかく、商品化・Webサービス化しないなら、気にすることではないでしょう。

昨日に検証したfindContoursもPylsd(LSD)ぐらいに頑張ってくれれば、もっと使えるのですけどね。
findContoursは、次の記事で説明しています。

やはり、画像毎にパラメータ調整を行うのはちょっと違います。
毎回背景が同じで、同じような被写体なんて普通はありえません。

作物の形状測定などの限られたケースなら、ハフ変換で事足りるでしょう。
逆に、それほどの専門性を求められるなら、ハフ変換でパラメータ調整をした方がよいかもしれません。

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