完整版:Python----計算機視覺處理(Opencv:道路檢測完整版:透視變換,提取車道線,車道線擬合,車道線顯示)
一、透視變換?
? ? ? ? 將透視變換之后的圖像再繼續透視變換為原圖像
可參考Python----計算機視覺處理(Opencv:道路檢測之道路透視變換)
?導入模塊
import numpy as np
import cv2
輸入圖像?
img=cv2.imread('img_to_wrp.png')
?獲得透視變換矩陣
height, width, _ = img.shape
src = np.float32([[width // 2 - 75, height // 2],[width // 2 + 100, height // 2],[0, height],[width, height]])
dst = np.float32([[0, 0],[width, 0],[0, height],[width, height]])
M = cv2.getPerspectiveTransform(dst,src )
?創建一個三通道背景圖
wrp_zero=np.zeros_like(img_road1).astype(np.uint8)
color_wrp=np.dstack((wrp_zero,wrp_zero,wrp_zero))
組合車道線坐標
pts_left = np.transpose(np.vstack([left_fitx, ploty]))
pts_right = np.transpose(np.vstack([right_fitx, ploty]))
pts_middle = np.transpose(np.vstack([middle_fitx, ploty]))
繪制車道線
cv2.polylines(color_wrp, np.int32([pts_left]), isClosed=False, color=(202, 124, 0), thickness=15)
cv2.polylines(color_wrp, np.int32([pts_right]), isClosed=False, color=(202, 124, 0), thickness=15)
cv2.polylines(color_wrp, np.int32([pts_middle]), isClosed=False, color=(202, 124, 0), thickness=15)
將得到的車道線的像素點根據逆透視變換映射到原始圖像中
newwarp = cv2.warpPerspective(color_wrp, M, (img.shape[1], img.shape[0]))
二、圖像融合?
?將逆透視變換后的結果和原始圖像進行融合
result1 = cv2.addWeighted(img, 1, newwarp, 1, 0)
創建一個灰色背景三通道圖像
background_zero = np.zeros_like(img).astype(np.uint8) + 127
將原始圖像和灰色背景融合?
result = cv2.addWeighted(background_zero, 1, newwarp, 1, 0)
圖像合并?
concatenate_image1 = np.concatenate((img, img_wrp), axis=1)
concatenate_image2 = np.concatenate((result1, result), axis=1)
concatenate_image = np.concatenate((concatenate_image1,concatenate_image2), axis=0)
輸出圖像?
cv2.imshow('concatenate_image', concatenate_image)
cv2.waitKey(0)
三、完整代碼
# 讀取圖像
img = cv2.imread('road_polyfit.png')
height, width, _ = img.shape # 獲取圖像的高度和寬度 # 定義源點(src)和目標點(dst)進行透視變換
src = np.float32( [ [width // 2 - 75, height // 2], # 左側車道線的源點 [width // 2 + 100, height // 2], # 右側車道線的源點 [0, height], # 底部左側點 [width, height] # 底部右側點 ]
)
dst = np.float32( [ [0, 0], # 目標左上角 [width, 0], # 目標右上角 [0, height], # 目標左下角 [width, height] # 目標右下角 ]
) # 計算透視變換矩陣
M = cv2.getPerspectiveTransform(dst, src) # 創建一個與原圖像同樣大小的全黑圖像用于保存透視變換后的車道線
wrp_zero = np.zeros_like(img).astype(np.uint8) # 創建一個顏色圖像,用于繪制車道線
color_wrp = np.dstack((wrp_zero, wrp_zero, wrp_zero)) # 將黑色圖像復制成三個通道 # 組合車道線坐標
pts_left = np.transpose(np.vstack([left_fitx, ploty])) # 左側車道線的坐標
pts_right = np.transpose(np.vstack([right_fitx, ploty])) # 右側車道線的坐標
pts_middle = np.transpose(np.vstack([middle_fitx, ploty])) # 中間車道線的坐標 # 繪制車道線,使用指定的顏色和線寬
cv2.polylines(color_wrp, np.int32([pts_left]), isClosed=False, color=(202, 124, 0), thickness=15)
cv2.polylines(color_wrp, np.int32([pts_right]), isClosed=False, color=(202, 124, 0), thickness=15)
cv2.polylines(color_wrp, np.int32([pts_middle]), isClosed=False, color=(202, 124, 0), thickness=15) # 將得到的車道線的像素點根據逆透視變換映射到原始圖像中
newwarp = cv2.warpPerspective(color_wrp, M, (img.shape[1], img.shape[0])) # 將逆透視變換后的結果和原始圖像進行加權融合,顯示最終效果
result1 = cv2.addWeighted(img, 1, newwarp, 1, 0) # 創建一個灰色背景圖像,用于顯示結果
background_zero = np.zeros_like(img).astype(np.uint8) + 127 # 創建一幅灰色圖像 # 經過加權融合得到結果
result = cv2.addWeighted(background_zero, 1, newwarp, 1, 0) # 拼接圖像以便進行可視化
concatenate_image1 = np.concatenate((img, img_wrp), axis=1) # 拼接原始圖像和變換后的圖像
concatenate_image2 = np.concatenate((result1, result), axis=1) # 拼接加權融合的結果
concatenate_image = np.concatenate((concatenate_image1, concatenate_image2), axis=0) # 縱向拼接完整圖像 cv2.imshow('concatenate_image', concatenate_image) # 所有結果拼接的圖像
cv2.waitKey(0) # 等待按鍵以結束
四、庫函數?
4.1、transpose()
返回軸轉置d 的數組。
對于一維數組,這將返回原始數組的未更改視圖,因為轉置d 向量只是相同的向量。 要將一維數組轉換為二維列向量,需要一個額外的維度 必須添加,例如,實現此目的,就像 . 對于 2-D 數組,這是標準矩陣轉置。 對于 n-D 數組,如果給定了軸,則它們的順序表示 軸被置換(參見 Examples)。如果未提供 axes,則 。np.atleast_2d(a).T
a[:,?np.newaxis]
transpose(a).shape?==?a.shape[::-1]
numpy.transpose(a, axes=None)
方法 | 描述 |
---|---|
a | Input 數組。 |
axes | 如果指定,則它必須是包含排列的 Tuples 或 List 的 [0, 1, ..., N-1] 其中 N 是?a?的軸數。陰性 indices 還可用于指定軸。返回的 數組將對應于輸入的軸編號。 如果未指定,則默認為 ,這將反轉 軸的順序。axes[i] range(a.ndim)[::-1] |
4.2、concatenate()
????????沿現有軸連接數組序列。
numpy.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")
方法 | 描述 |
---|---|
a1, a2, … | 數組必須具有相同的形狀,但維度 對應于?axis?(默認情況下是第一個)。 |
axis | 數組將沿其連接的軸。如果 axis 為 None,則 數組在使用前被展平。默認值為 0。 |
out | 如果提供,則為放置結果的目標。形狀必須為 correct,匹配?concatenate?在 no out 參數。 |
dtype | 如果提供,目標數組將具有此 dtype。不能 與?out?一起提供。 |
casting | 控制可能發生的數據類型轉換。默認為 'same_kind'。 有關選項的描述,請參閱鑄造。 |
4.3、polylines()
????????繪制多條多邊形曲線。
cv.polylines( img, pts, isClosed, color[, thickness[, lineType[, shift]]] ) -> img
方法 | 描述 |
---|---|
img | 圖像。 |
pts | 多邊形曲線數組。 |
isClosed | 指示繪制的多段線是否閉合的標志。如果它們是閉合的,則該函數將從每條曲線的最后一個頂點到其第一個頂點繪制一條線。 |
color | 多段線顏色。 |
thickness | 多段線邊線的粗細。 |
lineType | 線段的類型。請參閱線型 |
shift | 頂點坐標中的小數位數。 |
4.4、addWeighted()
cv.addWeighted( src1, alpha, src2, beta, gamma[, dst[, dtype]] ) -> dst
方法 | 描述 |
---|---|
src1 | first input 數組。 |
alpha | 第一個數組元素的權重。 |
src2 | 第二個輸入數組的大小和通道號與 src1 相同。 |
beta | 第二個數組元素的權重。 |
gamma | 添加到每個 sum 的標量。 |
dst | output 數組,該數組具有與 input 數組相同的大小和通道數。 |
dtype | 輸出數組的可選深度;當兩個輸入數組具有相同的深度時,可以將 dtype 設置為 -1,這相當于 src1.depth()。 |