OpenCV?NAO機器人輔助撿球丟球流程分析
1. 概述
NAO機器人身高58cm,體重5.4kg。主要硬件包括CPU、主板、揚聲器、話筒、紅外線、相機、超聲波(聲吶)、傳感器、電機、語音合成器、陀螺儀等。實驗室中NAO機器人的型號為NAO
H25,其構造如下:

NAO機器人的操作系統(tǒng)為Gentoo Linux,它支持Windows、Linux、Mac OS等操作系統(tǒng)的遠程控制,可以在這些平臺上編程控制NAO。頭部CPU運行Linux內核,支持Aldebaran Robotics內核NAOqi,NAOqi提供了一組應用程序接口(API)用于操作機器人,如控制機器人運動、拍攝、聲音識別、讀傳感器值等。使用C++、Python、.Net、Java、Matlab等語言可以調用這些API。
本項目使用NAO機器人識別球并撿起,然后將其扔到指定位置。主要涉及圖像的獲取、濾波、目標物體定位和NAO機器人的運動控制。
整個流程大致為:獲取機器人頭部攝像頭的圖片,對圖片進行一系列處理后,再根據霍夫圓檢測函數求出圖片中球的坐標。這樣循環(huán)求取球的坐標,先左右移動機器人使球位于圖像的中間以防止球超出攝像頭范圍,再前后移動機器人使球位于圖片的最下方以便于接下來切換到嘴部攝像頭檢測球。接著讓機器人向前移動固定距離,然后切換到嘴部攝像頭進行近距離檢測,與頭部攝像頭檢測類似,循環(huán)檢測并調整球的坐標到預先設定的像素范圍內,即可調用錄制好的抓球動作將球撿起。最后機器人檢測垃圾桶的輪廓,過濾無關輪廓并根據輪廓重心和輪廓面積移動到指定位置,然后將球扔入垃圾桶內即可。
需要解決的問題包括:
(1)OpenCV:圖像指定顏色提取與二值化,噪聲濾除、圓和垃圾桶的輪廓檢測與定位
(1)NAO機器人:攝像頭圖像的獲取、Animation模式下指定動作幀的錄制、根據檢測到的輪廓坐標進行運動控制
2. 相關技術
本項目主要用到了NAO機器人的運動控制和OpenCV圖像處理等技術。
2.1 NAO機器人
(1)啟動與連接
按下NAO機器人胸口的按鈕即可啟動NAO。用戶可以通過以太網或Wi-Fi兩種方式連接計算機。第一次使用時先用以太網線連接NAO機器人,在機器人啟動之后再按下其胸口的按鈕,它會報出機器人的IP地址,接著在瀏覽器打開這個IP地址即可進入NAO機器人的設置界面。該界面可以設置機器人的揚聲器音量,Wi-Fi連接、語言等功能。接著通過這個IP地址和固定端口號9559,即可使用C++、Python等編程語言通過TCP/IP協議與NAOqi進行連接,調用NAOqi的API即可實現對NAO機器人的操作。
另外,NAO實際是一臺計算能力足夠強的計算機,它還提供了SSH(安全外殼協議)的遠程登錄(Telnet)和文件傳輸(FTP)服務。通過遠程登錄和文件傳輸服務,可以像是用一臺裝有Linux操作系統(tǒng)的計算機那樣使用NAO。
(2)NAOqi
在NAO上執(zhí)行NAOqi是通過一個代理程序(Broker)完成的。啟動機器人時,代理程序會自動加載/etc/naoqi/autoload.ini文件,這個文件中指定了需要加載NAOqi的哪些庫,這些庫文件位于/usr/lib/naoqi目錄下。一個庫包含一個或多個模塊,每個模塊定義了多種方法。例如NAO的運動功能都放在ALMotion模塊中,讓機器人完成移動、轉頭、張手等動作分別要調用ALMotion模塊中的moveto()、setAngles()、OpenHand()等方法。
使用NAOqi模塊時,不需要像普通Python程序那樣用import語句導入所有模塊,模塊通過Broker通告它所提供的方法。通過Broker,任何模塊都可以找到所有已經通告的模塊及方法。
Broker主要由兩個作用:直接服務,即查找模塊和方法;網絡訪問,即從Broker進程外部調用模塊方法。Broker既是一個可執(zhí)行程序,也是一個服務器,可以對指定的IP和端口監(jiān)聽遠程命令。通過IP和端口與調用NAOqi模塊的程序,既可以在機器人上運行,也可以在遠程計算機上直接運行。一般來說Broker是透明的,在大部分情況下,編程時可以不考慮Broker,調用本地模塊的代碼與調用遠程模塊的代碼是一樣的。
2.2 Choregraphe
Choregraphe是NAO提供的編程環(huán)境,用該軟件可以創(chuàng)建應用于NAO機器人的行為模塊,并可以將其上傳至所連接的機器人進行測試。Choregraphe采用的是圖形化編程,創(chuàng)建復雜性為模塊不需要用戶編寫任何一條代碼,Choregraphe也提供用戶自定義功能,允許使用Python語言編寫自定義模塊。在本次撿球程序中主要使用了該軟件的時間軸指令盒和Animation模式來錄制用戶想讓機器人完成的動作。
2.3 OpenCV
OpenCV是一個跨平臺的計算機視覺庫,它是由英特爾公司發(fā)起并參與開發(fā),以BSD許可證授權發(fā)行,可以在商業(yè)和研究領域中免費使用。OpenCV可用于開發(fā)實時的圖像處理、計算機視覺以及模式識別程序。OpenCV可用于解決如下領域的問題:增強現實、人臉識別、手勢識別、人機交互、動作識別、運動跟蹤、物體識別、圖像分割、機器人。
OpenCV使用C++語言編寫,它的主要接口也是C++語言,但是依然保留了大量的C語言接口。該庫也有大量的Python,Java and MATLAB的接口,本項目中主要在Python中使用OpenCV接口。
3. 總體設計與詳細設計
系統(tǒng)主要分為三大模塊,分別為:姿勢控制、運動控制、OpenCV視覺處理。
3.1 系統(tǒng)模塊劃分
一、姿勢控制
由于需要根據攝像頭的圖像識別球,而機器人的不同姿勢決定了機器人的視覺范圍,所以在不同情況下需要指定機器人保持不同的姿勢。
二、運動控制
機器人需要抓球與扔球,而整個動作序列通過填寫不同幀時刻各個關節(jié)的角度值則不僅難以達到理想的效果,而且會花費大量的精力。所以這里通過Choregraphe的Animation模式對動作的關鍵幀進行錄制。
三、OpenCV視覺處理與機器人移動
完成抓球和丟球最核心的工作就是對攝像頭獲取的圖像進行處理并控制機器人的移動,圖像處理主要通過OpenCV提供的API對圖像進行去噪、模糊、顏色提取、輪廓檢測,而機器人的移動主要是通過獲取的輪廓的像素信息控制機器人移動到指定位置。
3.2 主要功能模塊
一、姿勢控制
如下圖所示,NAO機器人使用旋轉集合橫滾(roll)、俯仰(pitch)和偏轉(yaw)表示運動姿態(tài),分別對應繞X、Y、Z軸方向上的旋轉。在描述關節(jié)的運動范圍時,沿旋轉軸順時針方向轉動為負,逆時針轉動為正。

NAO機器人的每個關節(jié)名稱由部件名稱+姿態(tài)名稱組成,如HeadYaw表示機器人頭部左右旋轉的關節(jié)。經過測試,本項目中初始化動作為ShoulderPitch為80度,ShoulderRoll為20度,HipPitch為-25度,KneePitch為40度,AnklePitch為-20度,其它關節(jié)均為0度。將上述關節(jié)和角度寫入一個list中,然后調用ALMotion中的angleInterpolationWithSpeed函數調整機器人的姿勢。
二、運動控制
打開Choregraphe-右鍵創(chuàng)建指令盒-時間軸,雙擊創(chuàng)建的時間軸即可編輯機器人的動作,可以在不同幀時刻存儲NAO身體某個關節(jié)或全部關節(jié)的角度信息來完成動作的錄制。而NAO機器人在正常模式下所有關節(jié)的剛度為1,不能移動其關節(jié)。而在Animation模式下,機器人的眼睛和腳部LED的顏色如果是橙色則表示剛度為1,可通過觸摸其手部和腳部讓LED的顏色變?yōu)榫G色,這就可以隨意的調整機器人的不同關節(jié),調整完后在軟件中記錄這個關鍵幀即可。
兩個關鍵幀之間的動作可以通過貝塞爾曲線來模擬生成一個平滑的動作曲線以保證機器人動作的正常執(zhí)行。調整完動作后,可以生成對應的C++/Python代碼。
三、OpenCV視覺處理與機器人移動
(1)NAO攝像頭的捕捉
NAO頭部有兩個相機,用于識別視野中的物體,其中前額相機主要用于拍攝遠景圖像,嘴部相機主要用于拍攝下方圖像。相機的可選分辨率有6種,最高為1280x960px,這里設置為640x480px。
獲取圖像:首先連接ALVideoDevice模塊,再調用subscribe函數訂閱圖像,該函數可以設置圖片的分辨率、獲取圖片的色彩空間等參數。最后調用getImageRemote即可從攝像頭中獲取一個圖像數組,其中0號和1號元素為圖像的寬、高,6號元素為圖像數據。獲取圖像后將圖像轉為numpy格式并返回。
與RGB相比,HSV色彩空間不會隨光照強度的變化而發(fā)生劇烈變化,目標物體顏色值也不會出現較大的偏差,一定程度上減弱了光照條件對機器人視覺系統(tǒng)的影響,增強了機器人視覺系統(tǒng)的自適應能力。所以獲取RGB色彩空間的圖像之后,通常將其轉化為HSV色彩空間進行檢測。
def getImage(IP, PORT, flag):
camProxy = ALProxy("ALVideoDevice", IP, PORT)
resolution = 2 # 640x480
colorSpace = 11 # RGB
# 頭部/嘴部攝像頭
camProxy.setParam(18, flag)
videoClient = camProxy.subscribe("python_client", resolution, colorSpace, 5)
naoImage = camProxy.getImageRemote(videoClient)
camProxy.unsubscribe(videoClient)
imageWidth = naoImage[0]
imageHeight = naoImage[1]
array = naoImage[6]
im = Image.frombytes("RGB", (imageWidth, imageHeight), array)
ci = np.array(im) # 轉化成numpy格式圖像
r, g, b = cv2.split(ci) # opencv的圖像為BGR因此需要轉換一下
ci = cv2.merge([b, g, r])
return ci
(2)球檢測
紅球主要通過霍夫圓變換進行檢測,具體步驟如下:
1、從機器人的相機中獲取圖像,并將其轉化為HSV色彩空間的圖像。
2、接著根據HSV顏色范圍表提取指定顏色范圍,以綠球為例,其HSV的范圍為[35,43,46]至[77,255,255],調用inRange函數提取出綠色色彩空間。但實際測試效果并不好,會將周圍環(huán)境中無關的內容提取出來,而實驗中使用的綠球較鮮艷,經測試將HSV的下限中的S(飽和度)調高至128即可較好的提取出綠色色彩空間。
3、對圖像進行高斯模糊以消除圖片中的噪聲,內核取7x7的矩陣。
4、進行一次開操作,即先腐蝕后膨脹以進一步消除噪聲。
5、觀察此時的圖像,除了被檢測的球,還有很多位置有斷斷續(xù)續(xù)的白色。所以先取反然后進行三次閉操作(先膨脹再腐蝕),內核取15x15的矩陣。
6、此時得到的二值圖較為理想,圖像處理過程結果如下圖所示:

7、調用HoughCircles進行霍夫圓檢測,具體參數如下:
cv2.HoughCircles(np.uint8(dilated),cv2.HOUGH_GRADIENT,1,100,param1=100,param2=7,minRadius=2, maxRadius=60)
其中:
第一個參數為輸入圖像
第二個參數檢測方法選擇霍夫梯度法
第三個參數為累加面分辨率大小,這里設置為1表示分辨率與原圖像相同
第四個參數為param1,即Canny邊緣檢測的高閾值
第五個參數為param2,其值越小檢測圓的限制就越低
第六個參數為檢測的最小圓半徑
第七個參數為檢測的最大圓半徑
8、如果濾波效果好的話,能檢測出圖中所有圓圓心坐標和半徑,這里假設僅有一個綠球,所以最終判斷如果檢測出來的結果中只有一個圓的話,返回該圓的圓心坐標。
以上即為檢測球圓心的步驟,具體調用時,連續(xù)獲取10次攝像頭圖像并檢測球圓心,排序后,如果中間元素為(0,0)表示沒有檢測到球,否則將其返回。
(3)抓球
由于NAO機器人蹲下抓取地上的球時姿勢保持太久容易發(fā)熱導致機器人需要散熱才能繼續(xù)使用,由于這需要大量時間和經驗,而實訓時間有限,所以這里將球放置在高21cm的平臺上供機器人抓取。
首先在Choregraphe中打開Animation模式,然后記錄3個關鍵幀:
(1)將手掌打開以防止手觸碰到平臺部分
(2)將機器人的右手移動到球上方的一點的高度
(3)接著將右手從右往左移動以保證球能在手掌中。
將上述三個關鍵幀生成代碼后在Python中測試,開始上述動作之前需要調用ALMotion中的openHand函數打開機器人的手掌,上述動作完成后再調用closeHand抓起球。
(4)球定位
將機器人放置到固定位置,然后測試上述的動作能順利的將球抓起。記錄此時機器人與球的相對位置:前腳離平臺9cm、瓶蓋圓心與右腿膝蓋的右側平行。接著在這個位置調用之前的球檢測函數,在機器人使用嘴部攝像頭且髖部HipPitch和膝部KneePitch為-25和+40時,球的坐標大概在(523.5,426.5),由于此時機器人離球很近,所以這里允許X、Y坐標都有25像素的偏差,經測試在這個偏差范圍內可以將球抓起。
上述為嘴部攝像頭的參數確定,而剛開始由于機器人離球有一定距離,需要用前額攝像頭拍攝球。所以剛開始將機器人保持在固定動作,然后用前額攝像頭檢測球,根據檢測出的球坐標對(x,y)進行調整。首先希望球位于到攝像頭的最底端,這里實時檢測球的位置,讓機器人向前移動,將y增大到430以上。接著希望球能位于攝像頭的最中心,所以實時檢測球將其x坐標調整到290~350之間。
接著讓機器人前進,直到能從嘴部攝像頭中檢測到綠球。根據前面的測試,將球坐標穩(wěn)定于(523.5,426.5),且允許有25px的偏差即可。所以與前額攝像頭的步驟一樣,先調整y坐標再調整x坐標。
這里要注意的是,由于ALMotion模塊中機器人前進或后退的函數執(zhí)行過程中會的受一些客觀條件的影響,機器人往往會往左或往右偏離一定的角度。所以在機器人左右或前后移動后,判斷其x或y坐標的偏差,如調整x坐標時,y坐標的偏差超過一定閾值則認為機器人的移動出現了偏離,所以向左或向右旋轉一定的角度進行補償。
最后調用之前錄制好的抓球動作進行抓球即可。
(5)垃圾桶定位
這里希望將抓取到的球扔到紅色垃圾桶中,同樣通過機器人的攝像頭獲取圖像,然后進行均值偏移濾波和中值濾波,再將圖像轉到HSV空間,提取紅色的HSV范圍。接著將結果進行二值化,再調用OpenCV中的findContour函數檢測輪廓,這里根據垃圾桶與機器人的距離等參數測試,可得到垃圾桶在一定距離內的面積范圍,根據這個范圍選取出一個輪廓,再通過輪廓的結果可以計算出輪廓的重心坐標。
將上述檢測垃圾桶重心的功能封裝成一個函數,其返回值為輪廓的重心坐標。這里將垃圾桶放置在機器人的左側。在機器人抓起球后,首先后退25cm左右,這樣做是防止機器人旋轉時被平臺擋住。然后將機器人旋轉60°,保證垃圾桶在機器人攝像頭范圍內。后續(xù)步驟與檢測球的步驟類似,首先調整機器人的Y坐標至340左右,接著調整X坐標在[300,335]范圍內,最后機器人前進一定的距離即可走到垃圾桶的面前。

(6)丟球
同樣通過Choregraphe的Animation模式來錄制動作,只需記錄機器人手部的動作,共記錄兩幀:張開右臂和移動右臂到正中間。由于垃圾桶的直徑相較于球來說大得多,所以允許的偏差范圍也更大,成功率也更高。
生成Python代碼,執(zhí)行上述動作無誤后,調用ALMotion模塊中的openHand將球放入垃圾桶中。
4 視頻展示
NAO機器人識別球并抓取丟到垃圾桶
識別的慢是這個NAO機器人內部的伺服驅動模塊壞了,調用它的前進函數就會走歪。我就把步幅放慢,慢慢識別,同時還有左右走歪調整的函數。換一個沒壞的NAO機器人就不會有這個問題了。
到此這篇關于OpenCV NAO機器人輔助撿球丟球的文章就介紹到這了,更多相關OpenCV 機器人撿球丟球內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在echarts中圖例legend和坐標系grid實現左右布局實例
這篇文章主要介紹了在echarts中圖例legend和坐標系grid實現左右布局實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05

