由於我們的實驗場地並不是一根純黑線,中間的交線會對識別造成一定的影響,從而導致無人機在交線處飛偏,所以就想識別交點座標,保證無人機始終在直線上飛行,最後的實驗結果也很理想。
識別交線**是在網上看到的一段**,後來發現它的演算法思路很新奇,且應用過程中發現它的用武之地還蠻多的。
演算法思路:
這是一張二值化後的圖,對應畫素值:白色:255,黑色:0。 我用數值表示為:
這是一張5*7大小的二值圖,白色畫素值為255,黑色畫素值為0,我的目的是要求得(3,4)這個交點座標。以求x座標為例,先將每一列的值相加存入陣列得到 [255, 255, 1785, 255, 255] ,可以看到出現了乙個最大值1785,然後將相鄰的列相減(從第二列開始,後一列減去前一列)的值存入另乙個陣列得到 [0,1530,-1530,0] ,可以看到出現了乙個極大值和極小值,而這兩個值對應的索引(列號)就是我們需要的值。取得極大值的索引:2; 極小值的索引: 3 。對應二值圖可以看到,2就是我們需要求的x座標的左鄰列,3+1 就是x座標的右鄰列。最後求的 x = (2+4)/2 = 3 。同理,y= (3 +5 )/2 = 4 。
frame = imutils.resize(frame, width=160) #調整大小
gray = cv2.cvtcolor(frame, cv2.color_bgr2gray)
ret, th1 = cv2.threshold(gray, 80, 255, cv2.thresh_binary_inv) #轉化為二值圖
mask = cv2.dilate(th1, none, iterations=1) #膨脹一下,補足一些殘缺部分
roimask = mask[0:120, 50:110]
cnts2 = cnts2[0] if imutils.is_cv2() else cnts2[1]
if (len(cnts2) > 0):
#取得面積最大的輪廓並重繪(減少噪音干擾)
area = [cv2.contourarea(i) for i in cnts2]
area = np.array(area)
index = np.argmax(area)
img = np.zeros(roimask.shape)
im = cv2.drawcontours(img, cnts2, index, 255, -1)
#求交點x座標 (可以封裝成函式)
x_acc = np.sum(im, axis=0)
x_diff = np.diff(x_acc)
x_index1 = np.argmax(x_diff)
x_index2 = np.argmin(x_diff) + 1
x_max = max(x_diff)
x_min = min(x_diff)
if (x_max < 1000 and x_min > -1000):
postion_x = 80 #影象中點
else:
postion_x = (x_index1 + x_index2) // 2 + 50 #roimask取的範圍在[50,110],所以+50
# 求交點y座標
y_acc = np.sum(im, axis=1)
y_diff = np.diff(y_acc)
y_index1 = np.argmax(y_diff)
y_index2 = np.argmin(y_diff) + 1
y_max = max(y_diff)
y_min = min(y_diff)
if (y_max < 1000 and y_min > -1000):
postion_y = 60 #影象中點
else:
postion_y = (y_index1 + y_index2) // 2
else:
postion_x = 80
postion_y = 60
cv2.circle(frame, (postion_x, postion_y), 4, (0, 0, 255), -1) #畫出交點
print('postion_x,postion_y', postion_x, postion_y)
cv2.imshow('mask', mask)
cv2.imshow('frame', frame)
cv2.waitkey(0)
結果圖:
**說明:
roimask = mask[0:120, 50:110]只取了二值圖中間一部分[50,110]來求解,因為無人機在飛行起點與終點,左右兩邊直線外的影象會帶來干擾,索性只取了中間一段來求交點。當無人機飛出了終點,也就是cnts2沒有輪廓點了,可以做額外的動作,比如降落。cnts2 = cnts2[0] if imutils.is_cv2() else cnts2[1]
if (x_max < 1000 and x_min > -1000):這裡做了乙個最大最小值判斷,如果影象上不存在交點,只是一根單純的直線。例如下圖,它只能找到直線的中點y座標。postion_x = 80
else:
postion_x = (x_index1 + x_index2) // 2 + 50
這時x座標應為影象的中點(或者往某一方向飛行所需的定值)。所以,用這個演算法巡線也完全ok。( // 2 為取整。)
缺陷:飛行時需將無人機擺正(不用完全與直線重合),因為演算法是對畫素的操作,如果無人機與直線傾斜的角度大了,得到的影象存在一定角度,演算法就失效了。
其它應用:
1、 繞矩形框飛行,正如乙個矩形框的拐角,可以作為條件判斷來控制無人機的飛行方向。
2、在交點處懸停
矩形框**沒有測飛過,因為沒有場地。
無人機實驗筆記(提取目標區域)
無人機飛行過程中,飛的越高,視野範圍也越遠,而所需要的區域只是一部分,額外的區域都會成為干擾,那麼就需要提取目標區域。這是我們的高空俯檢視,從圖中看出,我們的目標區域明顯的特點是 很大面積的白色的底。那方法就顯而易見了,先刪選出白色區域,再提取輪廓點,最後根據輪廓點在原圖提取出目標區域。frame ...
顛覆 行業應用無人機帶來石油管道巡線全新解決方案
應用背景 石油管道是我國陸上油氣資源的主要運輸途徑,截至目前為止,我國已建油氣管道總長度約為 13 萬公里,部分石油管道由於建造時間早,已有 20 餘年的執行歷史,零件老化 管道變薄 外保護破損的情況常有發生。傳統的石油巡檢以人工巡護和電子感應巡檢作為主要巡檢手段。但傳統的人工巡檢花費較多的人力與時...
玩具無人機改18650電池實驗
玩具四軸飛行器無人機原裝電池只有幾百mah,為了延長飛行時間,嘗試用手頭3300mah的18650電池改裝,本電池實際稱重49g。1 焊接改裝好插頭,進行實驗 2 猛啟動會啟動不了報錯,輕輕啟動可以啟動起來,逐漸加速,但是在達到飛機離地的轉速以前,會掉電。3 究其原因,不外乎電池限流太小,苦於手頭無...