2022年4月23日土曜日

PiCar-Xでlane detection(04) PiCameraから画像の取り込み

 今回は、手順1番目のPiCameraから画像の取り込みについてです。

1.PiCameraから画像の取り込み

2.オリジナル画像から作業領域をクロップ

3.画像をBGRからHSVへ変換

4.OpenCV – inRangeで画像を2値化

5.OpenCV – cannyによるエッジ検出

6.region of interest(注目する領域)を設定

7.OpenCV – HoughLinesPによる直線の検出


一般的にpythonからPicameraを制御するためにはpicameraパッケージを使います。

【プログラム例】

import time
import picamera

# 写真の保存場所
CAM_DIR = "/home/pi/picar-x/Picamera/"

with picamera.PiCamera() as camera:


 while True:
   try:
     camera.resolution = (640, 480)     
     camera.start_preview()
     time.sleep(2)
     filename = time.strftime("%Y%m%d%H%M%S") + ".jpg"
     save_dir_filename = CAM_DIR + filename
     camera.capture(save_dir_filename)
   except KeyboardInterrupt:
     print("Ctrl+Cで停止しました")
     break
しかしここでは、画像・動画に関する処理機能をまとめたOpenCVライブラリと、画像処理ユーティリティーのimutilsモジュールをそれぞれインストールして使いました。

pip install opencv-contrib-python
pip install imutils

【プログラム例】
import cv2
import time
from imutils.video import VideoStream
from imutils import resize

# 写真の保存場所
CAM_DIR = "/home/pi/picar-x/Picamera/"

vs = VideoStream(src=0).start()

while True:
    try:
       # ファイルの取込
       img = vs.read()
       image = resize(img, width=640)

        
       filename = time.strftime("%Y%m%d%H%M%S") + ".jpg"
       save_dir_filename = CAM_DIR + filename
       cv2.imwrite(save_dir_filename,image)

    except KeyboardInterrupt:
      print("Ctrl+Cで停止しました")
      break

2022年4月4日月曜日

PiCar-Xでlane detection(03) OpenCVで画像の特定の色を抽出する

 前回の方法で車線を検出することが出来ましたが、白線も黄線も一緒に検出してしまいました。別に一緒に検出してダメなわけは無いのですが、注目している欲しい線分だけではなくその他の不要な線分も検出してしまうという事で、セレクトして線分を検出できればより質の高い前処理になると思います。

今回の注目点は、手順の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)