Opencv- Python處理車道線檢測
Opencv-Python處理車道線檢測
1.匯入
我們先要找一張圖片,對其進行檢測.
import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import math
# 讀入影象
img = cv2.imread('lu.jpg',3)
2.Canny邊緣檢測
為了突出車道線,我們對影象做邊緣處理.“邊緣”就是影象中明暗交替較為明顯的區域.車道線通常為白色或黃色,地面通常為灰色或黑色,因此車道線的邊緣處會有很明顯的明暗交替.
以Canny演算法為例,選取特定的閾值後,對灰度影象進行處理,即可得到的邊緣提取的效果圖.
# canny邊緣檢測
edges = cv2.Canny(img,150,350)
# 顯示影象
image1 = Image.fromarray(edges.astype('uint8'))
display(image1)
# 計算影象高度的一半
pic_height = img.shape[0]//2
3.霍夫直線檢測
# 引數有輸入的影象,畫素精度,弧度單位,最小點集,最小長度,最大間隔
lines = cv2.HoughLinesP(edges, 1,np.pi/360,10,minLineLength=100, maxLineGap=20)
``
cv2.HoughLinesP()函式原型:
HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None)
image: 必須是二值影象,推薦使用canny邊緣檢測的結果影象;
rho: 線段以畫素為單位的距離精度,double型別的,推薦用1.0
theta: 線段以弧度為單位的角度精度,推薦用numpy.pi/180
threshod: 累加平面的閾值引數,int型別,超過設定閾值才被檢測出線段,值越大,基本上意味著檢出的線段越長,檢出的線段個數越少。根據情況推薦先用100試試
lines:這個引數的意義未知,發現不同的lines對結果沒影響,但是不要忽略了它的存在
minLineLength:線段以畫素為單位的最小長度,根據應用場景設定
maxLineGap:同一方向上兩條線段判定為一條線段的最大允許間隔(斷裂),超過了設定值,則把兩條線段當成一條線段,值越大,允許線段上的斷裂越大,越有可能檢出潛在的直線段
4.計算線段中點
點座標(x, y)中,x代表圖片的列,y代表圖片的行
所以如果想在圖片中的位置(10, 0) 和 位置(0, 100)之間劃線,則正確的呼叫語句為:
1 import cv2 as cv
2 #在(10, 0)和(0, 100)之間畫條直線,直線的顏色為綠色
我們需要求出多餘線段的中點,只留圖片一半的下半部分.
線段中點座標公式 X=(x1+x2)/2,Y=(y1+y2)/2
length = []
filter_index_list = []
# 迴圈每個線段
for i in range(lines.shape[0]):
# 解析每個線段的端點座標
for x1, y1, x2, y2 in lines[i]:
# 計算中點座標
center_x = int((x1+x2)/2)
center_y = int((y1+y2)/2)
# 過濾掉在影象上半部分的座標
if(center_y > pic_height):
# 畫出符合條件的線段
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1)
# 統計個數
filter_index_list.append((x1, y1,x2, y2))
5.顯示結果
image1 = Image.fromarray(img.astype('uint8'))
display(image1)