試作ができたので試運転してみた。コースとしては一周ぐるっと回るようになっているのみ。映像から白線を認識して、白線中央を走るようになっている。カーブでは一部認識間違いが起きているものの、他の認識部分でカバーできている。白線検出は2値化×エッジ検出で行っている。
動画は左がシミュレータから受け取った画像に白線検出結果等を描写した結果で、右が白線検出のために画像処理した結果である。
制御方法は以下の通り。 - ステアリング - 両端の白線の中央を走るように、画面中央と白線中央の差分を使用してPID制御を行う。白線認識に関しては後述。 - 速度 - 目標速度で一定となるよう、アクセル強さを比例制御する。 - ステアリング角度が一定以上となった場合、カーブと判断し減速する。ただし加減速度は下回らないようにする。
条件は以下の通り。(自分用メモ)
- 640×480 20FPS
- 制御パラメータ
- st_param=[2.0, 0, 0]
- max_st=2
- mo_param=10.0
- stable_v=7
- min_v=3
- 白線位置
- x_1 = [0.05, 0.39]
- x_2 = [0.15, 0.43]
- x_3 = [0.3, 0.45]
- y_1 = 0.5
- y_2 = 0.4
- y_3 = 0.3
白線認識について
白線の認識方法は、左右各3領域(赤線)を水平方向にスキャンし、最も明るかったすべての点の位置の平均を白線位置としている。この「最も明るかった点」を検出するために、以下の方法を試した。
- 2値化
- エッジ検出
- 2値化×エッジ検出
2値化
2値化とは閾値を決めて、閾値以上であれば255、未満であれば0の2通りにする方法である。(本当は「最も明るかった点」を検出するだけであれば2値化は必要ないのだが、結果検証とのちの操作で必要。)
この方法でもある程度うまくいくのだが、地面の照り返し等で明るくなった場合に誤認識してしまう。以下の画像の右上の点がずれてしまっていることがわかる。このように単純に二値化をするだけではノイズが乗ってしまうことが分かった。
エッジ検出
2値化の欠点を補うために、エッジ検出でやってみた。エッジ検出は色が急激に変わる境界を検出する手法である。
これには2つの欠点がある。まず地面のざらつきなどを拾ってしまうことである。下のように道路の凸凹を検出してしまっていることが分かった。
2点目は影もエッジなので、その影響を受けてしまうということである。
2値化×エッジ検出
2値化、エッジ検出はそれぞれ利点はあるものの欠点もあった。両者の欠点としては端的に言えば誤検出してしまう点である。それであれば両者の結果をかけてしまえばいい。両者は検出箇所以外は0なので、明るい領域かつエッジであれば白線である可能性が高いということである。ちなみに領域が重なるよう、エッジのラインを太くしてから掛け合わせている。結果は最初に示した動画参照。 誤検出が大きければANDをとって、未検出が大きければORをとればよい。
補足
2値化×エッジ検出だと今回の条件ではうまくいくが、もちろん道路に書いてある「止まれ」なんかも認識してしまう。そのため、また別の識別するアルゴリズムは必要。
また白線認識のアルゴリズムのみに重点を置いて説明したが、検出位置やカメラの位置・角度も制御の安定に大きくかかわってくる。今回はトライアンドエラーで何とかした。