ビデオから車線を検出する必要があります。これが私のやり方です。
cv2.equalizeHist
で均等化cv2.adaptiveThreshold
を使用したしきい値(4)skimage.morphology.skeletonize
を使用してスケルトン化(5)cv2.HoughLines
を適用しますcv2.HoughLines
については、次のように設定しました。
rho
が正の場合(つまり、直線が右に傾斜している(ボトムアップ)場合、特定の角度にある場合にのみ線が描画されます(角度の範囲を設定します))。rho
が負の場合(直線が左(下から上)に傾斜している場合、特定の角度にある場合にのみ線が描画されます)これは線を引くための私のコードです:
lines = cv2.HoughLines(image_bin, 1, np.pi/180, 50)
try:
range = lines.shape[0]
except AttributeError:
range = 0
for i in xrange(range):
for rho, theta in lines[i]:
if rho > 0 and (np.pi*1/10 < theta < np.pi*4/10):
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0))
if rho < 0 and (np.pi*7/10 < theta < np.pi*9/10):
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0))
上記のcv2.HoughLines
関数で行ったことを行わなかった場合、不要な線がたくさん描画されると思います。
パラメータなどを調整したところ、かなり良い結果が得られましたが、それはたった1枚の写真です。変化し続けるビデオにとってはそれほど良いことではないと思います。私が最も気になるのは、必要な線(つまり車線)を描くためのアルゴリズムについてです。より良い方法はありますか?少なくとも私のよりはましだ。
これは私の結果です:
アプリケーションに確率的ハフライン変換を使用することを検討することをお勧めします。 OpenCVのPython APIでは、関数cv2.HoughLinesP
に実装されています。これにより、実際に線分が得られるため、エンドポイントを計算する必要がありません。また、標準のハフライン変換。
ただし、いくつかのトレードオフがあります。たとえば、線分をつなぎ合わせるロジックを追加する必要がある場合があります。一方で、それはそれほど悪いことではないことがわかりました。私のおもちゃプロジェクトの1つ(自動運転ミニチュアバス)は、このアプローチを使用し、別々の線分をつなぎ合わせると、標準のハフライン変換でラインがまったく得られないカーブした道路を扱いやすくなりました。 。
お役に立てば幸いです。
編集:線分の「ステッチ」の詳細に関しては、それはあなたが達成しようとしていることによって異なります。道路を表示したいだけで、線分の間にギャップがあることに満足している場合は、ステッチを行う必要はありません。すべての線分を表示するだけです。私のアプリケーションでは、車線の曲率を決定する必要があったので、車線の平均勾配を含む各道路車線のモデルを構築するためにいくつかのステッチを行いました。これは、車線の制御を担当するモジュールへの入力として使用されました。それに応じて車輪を動かすためのサーボ。
「ステッチ」とは、特に洗練されたものを意味するものではありませんが、それを実現するための特定のOpenCV機能を認識していません。同じ車線の一部である線分を関連付ける方法が必要でした。そこで、画像の上部から下に向かってHoughLinesP
から返された線分を処理し、各線分の傾きとy切片を使用して、線分が交差する場所を決定しました。