Python+OpenCVによる前方車両検出(1)
はじめに
前回、"単眼車載カメラによる前方車両の検出”という、広島工業大学の紀要に掲載されていた論文を読みました。
本手法は、走行空間モデルと横方向のエッジ画像の射影ヒストグラムを用いて、非学習ベース(CNNやSVMなどを使わない)で前方車両を検出する方法を提案していました。
今回からこの技術をpythonで実装していきます。
実装手順
本論文の処理フローは次のようになっています。
今回はPythonで消失点推定と探索領域の生成を実装します。
探索領域の生成
探索領域の生成では、走行している車線に内接した矩形領域(黄色い矩形)を生成します。
この矩形は消失点に向かって連続的に生成されるので、何らかの方法で消失点を求める必要があります。
前方カメラの消失点を求める方法として、車線を構成する白線の交点を用いる方法があります。
前に高効率に白線とその交点(消失点)の推定法を実装したので、今回はそれを使って探索領域の生成をやっていきます。
以下に消失点推定した結果を示します。
左右から中央にかけて伸び、画像中央辺りで交差している緑の直線が白線の検出結果になっており、中貫きの黄色い丸が推定した消失点です。
この2本の白線と消失点から探索領域を作成します。
探索領域を作成する際にはまず、2本の白線と矩形の底辺(を通る直線)の交点を求めます。
2点のXY座標のペアから直線を求める方法とその交点の求め方は以下の記事を参照してください。
具体的にはコードは次のようになります。
import numpy as np import cv2 import get_vanishing_point def linear(n1, n2): """ 2つのxy座標から直線の式 y = ax + bを求める """ if n2[0] - n1[0] == 0: return -1, -1 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): """ 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) if __name__ == "__main__": img = cv2.imread("img.png") # 消失点の座標cx, cyを求める # 実装自体は前回の記事を参照してください cx, cy = get_vanishing_point(img) indexes = get_lane_indexes(img) # 左右の白線の直線の式を求める la, lb = linear(indexes[1], [cx, cy]) ra, rb = linear(indexes[4], [cx, cy]) y = 300 #任意の高さ lx = (y - lb) / la rx = (y - rb) /rb lx, rx = int(lx), int(rx) img = cv2.line(img, (lx, y), (rx, y), (150, 220, 40), 1) cv2.imwrite("out.png", img)
出力画像は次のようになります。
左右の白線に接する水平線が引かれていることが確認できます。
この際の高さyを任意の範囲で変更した結果も載せます。
いい感じに路面に区画線?のようなものが引けましたね!
なんとなく昔良く遊んでたマリオゴルフのパターを思い出し、テンションが上がってきました。
※引用元 https://ameblo.jp/nataliayuta0814/entry-12634891125.html
最後に消失点推定と車線に隣接する線分の推定の一連の処理を動画にしてみました。
テスト用のデータの引用元
DrivingStereo | A Large-Scale Dataset for Stereo Matching in Autonomous Driving Scenarios