社会人研究者が色々頑張るブログ

pythonで画像処理やパターン認識をやっていきます

Python+OpenCVによる白線検出(2)

はじめにのはじめに

完成版の記事です nsr-9.hatenablog.jp

はじめに

nsr-9.hatenablog.jp

これの続きです。
今回は、白線候補点から白線(と消失点)を求める、Hypothesis Generation部分を実装します。

f:id:nsr_9:20210815135729p:plain

Hypothesis Generation

Hypothesis Generationでは、前のStepで検出した6点の白線候補点から、左右の白線を近似する直線の式を求めます。
そして、2本の直線の交点を消失点としてます。
非常にシンプルですね!

f:id:nsr_9:20210813180337p:plain

左の白線はP1とP3、右側の白線はP4とP6を通る直線の式を求めます。
2つの点を通る直線の式は、以前の記事を参照すると簡単に実装することができます。
nsr-9.hatenablog.jp

以下に、関係する部分のコードを抜粋しました。

def linear(n1, n2):
    a = (n2[1]-n1[1])/(n2[0]-n1[0])
    b = (n2[0]*n1[1]-n1[0]*n2[1])/(n2[0]-n1[0])
    return a, b

if __name__ == "__main__":
    p1 = [100, 100]
    p3 = [50, 50]
    a, b = linear(p1, p3)

aとbは直線の式における傾きと切片です。

また、消失点(2直線の交点)も以前の記事のコードを用いることで簡単に求める事ができます。
こちらも関係する部分を抜粋しました。

def linear(n1, n2):
    a = (n2[1]-n1[1])/(n2[0]-n1[0])
    b = (n2[0]*n1[1]-n1[0]*n2[1])/(n2[0]-n1[0])
    return a, b


def cross_point(n1, n2, m1, m2):
    a1, b1 = linear(n1, n2)
    a2, b2 = linear(m1, m2)

    if a1 == a2:
        return None, None
    return (b2-b1)/(a1-a2), (a1*b2-b1*a2)/(a1-a2)

実行例

今回作成した直線検出と消失点検出と、前回の候補点検出を組み合わせて実行してみました。
実行結果の中から特徴的なフレームをピックアップしたので、以下に示します。

出力例
frame 8
f:id:nsr_9:20210815141950j:plain
frame 67
f:id:nsr_9:20210815142003j:plain
frame 869
f:id:nsr_9:20210815142009j:plain

候補点を通る直線と、消失点が正しく求まっている事が確認できました。
frame 8の様にまだ検出点が正しく求まっていない状況だと、消失点は直感に反する位置に検出されています。
この様な誤検出は、後段の仮説検証プロセスで除去するのだと思います。

また、frame67, frame869はそれぞれ下り坂、上り坂のシーンです。
67の様な下り坂のシーンだと消失点は道路よりも下の位置に検出されます。
f:id:nsr_9:20210815144936j:plain

逆に869の様に上り坂のシーンだと道路よりも上の位置検出されます。
f:id:nsr_9:20210815145009j:plain

この特性を利用すれば、走行中の道路の勾配が推定できるかもしれませんね。

まとめ

今回は An Efficient Lane Detection Algorithm For Lane Departure Detection のHypothesis Generationを実装しました。
中学生くらいの時に勉強した数学(直線やその交点の式)が、具体的なアプリケーションに役立っている事を体感する事ができました。

最後に動画化した実行結果を添付します。 f:id:nsr_9:20210815150535g:plain