實(shí)驗(yàn)內(nèi)容:針對(duì)給定的視頻,利用圖像處理基本方法實(shí)現(xiàn)道路路沿的檢測(cè);
提示:可利用Hough變換進(jìn)行線檢測(cè),融合路沿的結(jié)構(gòu)信息實(shí)現(xiàn)路沿邊界定位(圖中紅色的點(diǎn)位置)。
處理視頻文件
處理視頻文件的主要流程如下:
讀取視頻→逐幀提取→路沿檢測(cè)→逐幀保存→輸出視頻
用python的OpenCV實(shí)現(xiàn)視頻文件的處理,用videoCapture打開視頻文件,讀取每一幀進(jìn)行處理,然后用videoWriter保存成視頻。
路沿檢測(cè)
路沿檢測(cè)的流程如下:
圖像預(yù)處理→邊緣檢測(cè)→Hough變換
圖像預(yù)處理
灰度化
從視頻中取出的每一幀是彩色圖像,我們可以先將它變成灰度圖像,即將圖像中的每個(gè)像素的RGB值(紅、綠、藍(lán))轉(zhuǎn)換為一個(gè)單一的灰度值。
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
灰度圖像只包含亮度信息,如圖1所示,而不包含顏色信息。這樣可以簡(jiǎn)化圖像,提高處理速度,突出圖像的結(jié)構(gòu),減少噪聲干擾。
圖1
均衡化
我們?cè)賹D像均衡化,python代碼如下。
image = cv2.equalizeHist(image)
圖像均衡化可以提高圖像的對(duì)比度,如圖2所示,突出圖像的細(xì)節(jié)輪廓與邊緣。
?
圖2
二值化
將灰度圖轉(zhuǎn)換為只有黑白兩種顏色的圖像,python代碼如下。
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
圖像二值化可以簡(jiǎn)化圖像信息,突出物體的輪廓,如圖3所示。
圖3
邊緣檢測(cè)
Canny邊緣檢測(cè)
Canny 邊緣檢測(cè)算法是John F.Canny于1986年開發(fā)出來(lái)的一個(gè)多級(jí)邊緣檢測(cè)算法,也被很多人認(rèn)為是邊緣檢測(cè)的最優(yōu)算法, 最優(yōu)邊緣檢測(cè)的三個(gè)主要評(píng)價(jià)標(biāo)準(zhǔn)是:
低錯(cuò)誤率: 標(biāo)識(shí)出盡可能多的實(shí)際邊緣,同時(shí)盡可能的減少噪聲產(chǎn)生的誤報(bào)。
高定位性: 標(biāo)識(shí)出的邊緣要與圖像中的實(shí)際邊緣盡可能接近。
最小響應(yīng): 圖像中的邊緣只能標(biāo)識(shí)一次。
Canny邊緣檢測(cè)算法步驟如下:
高斯濾波去噪→計(jì)算梯度幅值和方向→非極大值抑制→雙閾值處理
高斯濾波器去除噪聲
使用高斯濾波器對(duì)圖像進(jìn)行平滑處理,以減少噪聲的影響。
計(jì)算梯度幅值和方向
按照Sobel算子,運(yùn)用一對(duì)卷積陣列 (分別作用于 x 和 y 方向):
使用下列公式計(jì)算梯度幅值和方向:
梯度方向近似到四個(gè)可能角度之一(一般 0, 45, 90, 135)。
非極大值抑制
沿邊緣垂直方向?qū)ふ姨荻茸畲笾?,排除非邊緣像素?僅僅保留了一些細(xì)線條(候選邊緣)。
雙閾值處理
如果某一像素位置的幅值超過(guò)高閾值, 該像素被保留為邊緣像素。
如果某一像素位置的幅值小于低閾值, 該像素被排除。
如果某一像素位置的幅值在兩個(gè)閾值之間,該像素僅僅在連接到一個(gè)高于高閾值的像素時(shí)被保留。
在python中使用canny對(duì)圖像進(jìn)行邊緣檢測(cè),高閾值為175,低閾值為75。
image = cv2.Canny(image, 75, 175)
效果如圖4所示,可見(jiàn)canny算法可以有效的提取圖像的邊緣信息。
圖4
但是canny檢測(cè)出來(lái)的邊緣中噪聲比較多,我們?cè)偈褂酶咚篂V波器模糊一下圖像,在python中使用5×5的高斯濾波器模糊圖像。
image = cv2.GaussianBlur(image, (5, 5), 0)
效果如圖5所示,可見(jiàn)高斯濾波器模糊成功地去掉了一些噪聲。
圖5
Hough變換
Hough變換是一種用于檢測(cè)圖像中幾何形狀的技術(shù),將圖像由圖像空間變換為參數(shù)空間。它最初是由保羅·霍夫(Paul Hough)在1962年提出的,用于在圖像中檢測(cè)直線。后來(lái),這個(gè)方法被擴(kuò)展到檢測(cè)其他幾何形狀,如圓和橢圓。
一條直線在圖像二維空間可由兩個(gè)變量表示,在笛卡爾坐標(biāo)系中直線可由參數(shù)斜率k和截距b表示y=kx+b,在極坐標(biāo)系中可由參數(shù)極徑r和極角θ表示。
對(duì)于霍夫變換, 我們將用極坐標(biāo)系來(lái)表示直線,因此直線的表達(dá)式可為:
圖像空間中的一條線對(duì)應(yīng)Hough空間中的一個(gè)點(diǎn)。
圖像空間中的一個(gè)點(diǎn)對(duì)應(yīng)Hough空間中的一條線。
Hough變換的基本思想是將圖像中的像素點(diǎn)映射到參數(shù)空間中,并通過(guò)在參數(shù)空間中尋找峰值來(lái)檢測(cè)幾何形狀。對(duì)于直線檢測(cè),參數(shù)空間通常是極坐標(biāo)空間,其中每個(gè)像素點(diǎn)在參數(shù)空間中對(duì)應(yīng)一條直線。通過(guò)遍歷圖像中的像素點(diǎn),可以累加參數(shù)空間中相應(yīng)的位置,從而構(gòu)建一個(gè)累加器數(shù)組。然后,在累加器數(shù)組中找到峰值,這些峰值對(duì)應(yīng)于圖像中存在的直線。
Hough變換步驟:
離散化θ,θ=-45,0,45,90度。
按照點(diǎn)的坐標(biāo)(x,y)和每個(gè)角度θ求極半徑r:
統(tǒng)計(jì)(r,θ)出現(xiàn)的次數(shù)
最大次數(shù)3出現(xiàn)在(2,0°)和(3,90°),則對(duì)應(yīng)的圖像空間的線為x=2和y=3。
Hough變換的優(yōu)點(diǎn)是它對(duì)于噪聲和圖像變形具有一定的魯棒性。它可以檢測(cè)到不完整的、部分可見(jiàn)的或被噪聲干擾的幾何形狀。因此,Hough變換在計(jì)算機(jī)視覺(jué)領(lǐng)域中廣泛應(yīng)用于圖像分析、目標(biāo)檢測(cè)和特征提取等任務(wù)。
標(biāo)準(zhǔn)霍夫線變換
提供一組參數(shù)對(duì) (θ, rθ) 的集合來(lái)表示檢測(cè)到的直線,在OpenCV 中通過(guò)函數(shù) HoughLines來(lái)實(shí)現(xiàn)。
lines = cv2.HoughLines(edge, 1, np.pi / 180, 220)
統(tǒng)計(jì)概率霍夫線變換
這是執(zhí)行起來(lái)效率更高的霍夫線變換. 它輸出檢測(cè)到的直線的端點(diǎn) (x0, y0, x1, y1)。在OpenCV 中它通過(guò)函數(shù) HoughLinesP來(lái)實(shí)現(xiàn)。
lines = cv2.HoughLinesP(edge, 1, np.pi / 180, 100, minLineLength=50, maxLineGap=1)
Hough線變換應(yīng)用路沿檢測(cè)
本次我們采用標(biāo)準(zhǔn)Hough線變換來(lái)檢測(cè)路沿,經(jīng)過(guò)多次測(cè)試和調(diào)參,我們最后采用高斯模糊進(jìn)行圖像預(yù)處理,然后使用canny進(jìn)行邊緣提取,最后使用Hough線變換繪制直線。
def detect(image):
??? gauss = cv2.GaussianBlur(image, (5, 5), 0)
??? edge = cv2.Canny(gauss, 75, 175)
??? # 進(jìn)行Hough直線變換
??? lines = cv2.HoughLines(edge, 1, np.pi / 180, 220)
視頻檢測(cè)效果
第一個(gè)視頻是一個(gè)靜止不動(dòng)的路沿,檢測(cè)效果如圖6所示。
圖6
第二個(gè)視頻中,路沿開始變化起來(lái),檢測(cè)效果如圖7所示。
第三個(gè)視頻中出現(xiàn)了轉(zhuǎn)彎,檢測(cè)效果如圖8所示,因?yàn)槲覀冎蛔隽司€變化,因此對(duì)于路沿彎曲的部分只能畫出直線部分。
圖8文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-753825.html
代碼文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-753825.html
import cv2
import numpy as np
def detect(image):
gauss = cv2.GaussianBlur(image, (5, 5), 0)
edge = cv2.Canny(gauss, 75, 175)
# 進(jìn)行Hough直線變換
lines = cv2.HoughLines(edge, 1, np.pi / 180, 220)
# 繪制檢測(cè)到的直線
if lines is not None:
for rho, theta in lines[:, 0, :]:
if theta < 2:
continue
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 - 350 * (-b))
y1 = int(y0 - 350 * a)
x2 = int(x0 - 700 * (-b))
y2 = int(y0 - 700 * a)
cv2.line(image, (x1, y1), (x2, y2), (0, 255, 0), 4)
return image
video = cv2.VideoCapture('Task2/03.avi') # 打開視頻文件
# 獲取視頻的寬度和高度以及幀率信息
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = video.get(cv2.CAP_PROP_FPS)
# 創(chuàng)建VideoWriter對(duì)象,用于保存處理后的視頻
videoWriter = cv2.VideoWriter('Task2/video3.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))
while True:
have, frame = video.read() # 讀取當(dāng)前幀
if have:
frame = detect(frame) # 在這里對(duì)每一幀進(jìn)行處理
videoWriter.write(frame) # 將處理后的幀寫入輸出視頻文件
else:
break
video.release() # 釋放資源
videoWriter.release()
到了這里,關(guān)于【計(jì)算機(jī)視覺(jué)】【圖像處理綜合應(yīng)用】路沿檢測(cè)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!