pip install opencv-python==3.4.2.17
前回の記事は画像解析の「KerasでのData Augmentationの解説」を説明しました。今回はOpenCV + Pythonで直線検出を説明します。
OpenCVのハフ(Hough)変換は、画像の中から直線や図形を検出したい際によく用いられる手法の一つです。画像に含まれる直線、破線、点線を検出することができます。今回は以下の画像の線を消してみます。次には駐車場の白線検出をします。
import cv2
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline
img = cv2.imread("tic_tac_toe.png")
plt.figure(figsize=(5, 5))
img2 = img[:,:,::-1]
plt.xticks([]), plt.yticks([])
plt.imshow(img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imwrite("gray.jpg", gray)
img_p = cv2.imread('gray.jpg')
img_p2 = img[:,:,::-1]
plt.figure(figsize=(5, 5))
plt.xticks([]), plt.yticks([])
plt.imshow(img_p)
この変換で白と黒を逆転させ、白黒はっきりさせます。
Canny(const Mat& image, Mat& edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false)
image – 8ビット,シングルチャンネルの入力画像
edges – 出力されるエッジのマップ. image と同じサイズ,同じ型です
threshold1 – ヒステリシスが存在する処理の,1番目の閾値
threshold2 – ヒステリシスが存在する処理の,2番目の閾値
apertureSize – Sobel() オペレータのアパーチャサイズ
edges = cv2.Canny(gray,50,150,apertureSize = 3)
cv2.imwrite("edges.jpg", edges)
img_p = cv2.imread('edges.jpg')
img_p2 = img[:,:,::-1]
plt.figure(figsize=(5, 5))
plt.xticks([]), plt.yticks([])
plt.imshow(img_p)
対象の画像に対して、パラメータ値の調整が必要になります。ハフ変換の設定を説明します。
HoughLines(Mat& image, vector
image – 入力画像
lines – 検出された線分が出力されるベクトル
rho – ピクセル単位で表される投票空間の距離分解能
theta – ラジアン単位で表される投票空間の角度分解能
threshold – 投票の閾値パラメータ
minLineLength – 最小の線分長
maxLineGap – 2点が同一線分上にあると見なす場合に許容される最大距離
lines = cv2.HoughLinesP(edges,
rho=1,
theta=np.pi/360,
threshold=100,
minLineLength=200,
maxLineGap=6)
print(lines[:5])
直線検出して、赤線を引いて画像を作成します。
for line in lines:
x1, y1, x2, y2 = line[0]
# 赤線を引く
red_line_img = cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 3)
cv2.imwrite("output.jpg", red_line_img)
img_p = cv2.imread('output.jpg')
imgr_p2 = img[:,:,::-1]
plt.figure(figsize=(5, 5))
plt.xticks([]), plt.yticks([])
plt.imshow(img_p2)
for line in lines:
x1, y1, x2, y2 = line[0]
# 線を消す(白で線を引く)
no_lines_img = cv2.line(img, (x1,y1), (x2,y2), (255,255,255), 3)
cv2.imwrite("output2.jpg", no_lines_img)
img_p = cv2.imread('output2.jpg')
imgr_p2 = img[:,:,::-1]
plt.figure(figsize=(5, 5))
plt.xticks([]), plt.yticks([])
plt.imshow(img_p)
以下の駐車場の画像から白線検出します。
img_p = cv2.imread('parking.png')
imgr_p2 = img[:,:,::-1]
plt.figure(figsize=(8,8))
plt.xticks([]), plt.yticks([])
plt.imshow(img_p)
import cv2
import numpy as np
%matplotlib inline
img = cv2.imread("parking.png")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,90,450,apertureSize = 3)
lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi/360, threshold=60, minLineLength=10, maxLineGap=10)
for line in lines:
x1, y1, x2, y2 = line[0]
red_line_img = cv2.line(img, (x1,y1), (x2,y2), (0,0,255), 3)
cv2.imwrite("output3.jpg", red_line_img)
結果
CannyとHoughLinesPのパラメタを調整して、駐車場の白線検出できました。
img_p = cv2.imread('output3.jpg')
imgr_p2 = img[:,:,::-1]
plt.figure(figsize=(8,8))
plt.xticks([]), plt.yticks([])
plt.imshow(img_p)