前回の方法で車線を検出することが出来ましたが、白線も黄線も一緒に検出してしまいました。別に一緒に検出してダメなわけは無いのですが、注目している欲しい線分だけではなくその他の不要な線分も検出してしまうという事で、セレクトして線分を検出できればより質の高い前処理になると思います。
今回の注目点は、手順の3と4番目です。
1.PiCameraから画像の取り込み
2.オリジナル画像から作業領域をクロップ
3.画像をBGRからHSVへ変換
4.OpenCV – inRangeで画像を2値化
5.OpenCV – cannyによるエッジ検出
6.region of interest(注目する領域)を設定
7.OpenCV – HoughLinesPによる直線の検出
特定の色の抽出は2段階で行います。まず画像で使用されている色空間のRGB(OpenCVではBGRの順)をHSV色空間に変換します。これはRGB画像では光(照明)の影響を受けて同じ色でも濃い色・淡い色などの異なった色で表示されてしまう可能性がありますが、HSV色空間ではその影響を受けにくい為のようです。
その後inRange関数で画像を2値変換し、指定した特定の画素を抽出します。
OpenCVを使った色の抽出はネットにも沢山説明が載っていますので参考にしてください。
前回の『PiCar-Xでlane detection(02) 自動運転のための車線検出』のプログラムに必要な部分を追加して色の抽出を行ってみます。使用したのは以下の図です。
まず前回のプログラムそのままを使って処理を行ってみると
グレー変換
ノイズ除去のための平滑化
edgesの検出
Hough変換で直線の検出
予想したとおり全ての色の線が検出されました。
ここからは、特定の色抽出を行ってみます。
まずHSV色空間への変更
# HSV color space
image4 = cv2.cvtColor(image1, cv2.COLOR_BGR2HSV))
全く異なった色になってしまいました。これがHSV色空間というものなのですかね。良く分かりません。
つぎにinRange関数による画像の2値変換
inRange関数で画像を2値変換するのでグレー変換は削除しました。
# 色の抽出
# 黄色
lower = np.array([10, 100, 100])
upper = np.array([30, 255, 255])
# 白色
# lower = np.array([0, 0, 100])
# upper = np.array([180, 45, 255])
image_mask = cv2.inRange(image_blur, lower, upper)
黄色の線のみが残っています。
edges検出
Hogh変換による直線の検出
期待したとおりに黄色の線のみが検出できました。
全体のプログラムを掲載しておきます。
import cv2
import numpy as np
def img_show(image, text):
img_resize = cv2.resize(image, (640, 480))
cv2.imshow(text, img_resize)
cv2.waitKey(0)
cv2.destroyAllWindows()
def show_lines(image, lines):
lanelines_image = np.zeros_like(image)
if lines is not None:
for line in lines:
X1, Y1, X2, Y2 = line.reshape(4)
cv2.line(lanelines_image, (X1, Y1), (X2, Y2), (0,255,0), 2)
return lanelines_image
#画像の読み込み
image_path = 'input_dir/color.png'
image = cv2.imread(image_path)
img_show(image, 'original')
# HSV color space
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
img_show(image_hsv, 'hsv')
cv2.imwrite('output_dir/image_hsv.png', image_hsv)
# Gaussian blur
# 画像のぼかして平滑化することで、画像中のノイズ除去を行います
image_blur = cv2.GaussianBlur(image_hsv, (5,5), 0)
img_show(image_blur, 'blur')
cv2.imwrite('output_dir/image_blur.png', image_blur)
# 色の抽出
# 黄色
lower = np.array([10, 100, 100])
upper = np.array([30, 255, 255])
# 白色
# lower = np.array([0, 0, 100])
# upper = np.array([180, 45, 255])
image_mask = cv2.inRange(image_blur, lower, upper)
img_show(image_mask, 'mask')
cv2.imwrite('output_dir/image_mask.png', image_mask)
#edgesの検出
image_edges = cv2.Canny(image_mask,50,150)
img_show(image_edges, 'edges')
cv2.imwrite('output_dir/image_edges.png', image_edges)
#Hough変換による直線の検出
hough_lines = cv2.HoughLinesP(image_edges, 2, np.pi/180, 200, np.array([]), minLineLength= 10, maxLineGap=50)
image_lanelines = show_lines(image, hough_lines)
img_show(image_lanelines,'Hough lines')
cv2.imwrite('output_dir/image_lanelines.png', image_lanelines)