? ? ? ? 近期在做一個(gè)小車(chē)視覺(jué)循線的項(xiàng)目。小車(chē)將沿著一條線行駛,并用自帶的攝像頭拍攝道路前方的道路,行駛過(guò)程會(huì)遇到鈍角拐彎、弧線拐彎、直角拐彎這些特殊元素,小車(chē)需要在識(shí)別元素之后進(jìn)行合理地轉(zhuǎn)彎。
????????在網(wǎng)上看到大部分的循線方法主要是二值化之后遍歷圖像中的所有像素點(diǎn)然后求亮白色像素點(diǎn)的橫坐標(biāo)平均值,把平均值和圖像中心值做差求出小車(chē)的偏移量,再控制小車(chē)的運(yùn)動(dòng)。這樣的方法需要用二重for循環(huán)遍歷捕獲圖像的所有像素點(diǎn),效率低下。經(jīng)過(guò)本人的一位學(xué)長(zhǎng)的點(diǎn)撥,本人遂決定采用霍夫變換的方法進(jìn)行循線識(shí)別。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(圖片來(lái)自網(wǎng)絡(luò),侵刪)
思路:
1、首先,要選擇正確的識(shí)別區(qū)域。小車(chē)前方的一塊區(qū)域是小車(chē)即將到達(dá)的地方,而其他區(qū)域大都對(duì)識(shí)別沒(méi)有作用。所以,我們要ROI選取選擇合適的區(qū)域,來(lái)提高識(shí)別效率。
2、之后,對(duì)圖像進(jìn)行初步處理。這里,本人先將凸顯變?yōu)榛叶葓D像,然后進(jìn)行大津法的二值化,最后采用高斯濾波。大津法的二值化能夠根據(jù)圖像的具體亮度分布來(lái)決定閾值,能夠很好地把需要識(shí)別的白線分離出來(lái)而剔除干擾元素;高斯濾波能夠使圖像變得平滑,使接下來(lái)霍夫變換更加精準(zhǔn)。
3、接下來(lái)便是霍夫變換了。先把上一步得到的圖像進(jìn)行Canny邊緣檢測(cè),之后采用霍夫變換函數(shù)讀取圖像中的線段。注意這里要使用概率霍夫變換,否則得出的結(jié)果都是直線而非線段,無(wú)法得出偏差值。在這之后,我們就會(huì)得到所有線段始末兩點(diǎn)的橫縱坐標(biāo)。
4、讀取這些坐標(biāo)以后,我們需要兩個(gè)量:線段的平均偏移量和斜率接近于0的線段數(shù)量。前者用于檢測(cè)小車(chē)的偏移情況,否則則用于檢測(cè)是否有直角彎道。我們可以在用for循環(huán)遍歷所有線段始末兩點(diǎn)的坐標(biāo)之后,用橫坐標(biāo)累加值除以運(yùn)算的點(diǎn)的總數(shù)再減去圖像中心橫坐標(biāo)得出平均偏移量,用斜率計(jì)算公式[(y1-y2)/(x1-x2)]檢測(cè)線段是否水平或接近水平、統(tǒng)計(jì)這樣的線段數(shù)量。
5、最后進(jìn)行判斷:如果水平線段的數(shù)量大于0,則說(shuō)明小車(chē)遇到了直角彎道;否則沒(méi)有遇到直角彎道,小車(chē)應(yīng)當(dāng)按照偏移量的情況進(jìn)行打角轉(zhuǎn)彎文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-596743.html
?這邊附上一段用于檢測(cè)一幀圖像的代碼。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-596743.html
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
def midsearch():
img = cv2.imread("pic", -1) #導(dǎo)入圖片,參數(shù)請(qǐng)自行修改
h,w,c= img.shape
mid=img[int(h*0.7):int(h),int(0.25*w):int(0.75*w)] #ROI選區(qū),選擇圖像前面的一塊區(qū)域
hm, wm, cm = mid.shape
gray = cv2.cvtColor(mid, cv2.COLOR_BGR2GRAY) #設(shè)置圖像為灰度圖
ret, gray = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY) #大津法二值化
gray = cv2.medianBlur(gray, 11) #高斯濾波
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
orgb = cv2.cvtColor(mid, cv2.COLOR_BGR2RGB)
oShow = orgb.copy()
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 1, minLineLength=100, maxLineGap=60)#邊緣檢測(cè)之后霍夫變換得出直線
fn=0
n=0
tan=1.0
T=0.0
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(orgb, (x1, y1), (x2, y2), (255, 0, 0), 5)
n+=2;
fn+=x1
fn+=x2
if x1!=x2:
tan=(y1-y2)/(x1-x2)
if abs(tan)<0.1 and abs(x1-x2)>0.1*wm:
T+=1
else:
tan=1 #通過(guò)檢測(cè)直線斜率檢測(cè)是否遇到直角
average=fn/n
delta=average-wm/2
# print(T)
# print(delta)
# print(average)
# plt.subplot(121)
# plt.imshow(oShow)
# plt.axis('off')
# plt.subplot(122)
# plt.imshow(orgb)
# plt.axis('off')
# pylab.show()
return delta,T
def midjudge(delta,T):
#直角判斷
if delta>0 and T>=1:#右直角
print("右直角")
elif delta<0 and T>=1:#左直角
print("左直角")
else:
#正常行駛,包括鈍角以及圓弧的轉(zhuǎn)彎
if abs(delta)<=10:
print("直行")
elif delta>10:
print("右轉(zhuǎn)彎")
elif delta<-10:
print("左轉(zhuǎn)彎")
delta,T=midsearch()
midjudge(delta,T)
cv2.waitKey(0)
cv2.destroyAllWindows()
到了這里,關(guān)于基于Python OpenCV、使用霍夫變換的小車(chē)視覺(jué)循線識(shí)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!