平移/傾斜伺服裝置,幫助攝像機使用視覺自動跟蹤顏色對象。
現(xiàn)在我們將使用我們的設(shè)備幫助相機自動跟蹤顏色對象,如下所示:
OpenCV可免費用于學術(shù)和商業(yè)用途。它具有C ++,C,Python和Java接口,并支持Windows,Linux,Mac OS,iOS和Android。在我的一系列OpenCV教程中,我們將專注于Raspberry Pi(因此,Raspbian as OS)和Python。OpenCV專為提高計算效率而設(shè)計,專注于實時應(yīng)用。因此,它非常適合物理計算項目!
2.安裝OpenCV 3軟件包
我正在使用Raspberry Pi V3更新到最新版本的Raspbian(Stretch),因此安裝OpenCV的最佳方法是遵循Adrian Rosebrock開發(fā)的優(yōu)秀教程:Raspbian Stretch:在Raspberry Pi上安裝OpenCV 3 + Python 。
我嘗試了幾個不同的指南在我的Pi上安裝OpenCV。阿德里安的教程是最好的。我建議你按照他的指導方針一步一步地做同樣的事情。
完成Adrian的教程后,您應(yīng)該準備好在您的Pi上運行我們的實驗的OpenCV虛擬環(huán)境。
讓我們轉(zhuǎn)到我們的虛擬環(huán)境并確認OpenCV 3已正確安裝。
Adrian建議每次打開新終端時運行命令“source”以確保系統(tǒng)變量已正確設(shè)置。
接下來,讓我們進入我們的虛擬環(huán)境:
workon cv
如果您在提示符前面看到文本(cv),那么您就在cv virtualenvironment中:
Adrian提請注意,cv Python虛擬環(huán)境完全獨立,并與Raspbian Stretch下載中包含的默認Python版本隔離。因此,全局site-packages目錄中的任何Python包都不可用于cv虛擬環(huán)境。同樣,安裝在cv的site-packages中的任何Python包都不可用于全局安裝的Python。
現(xiàn)在,輸入你的Python解釋器:
python
并確認您運行的是3.5(或更高版本)版本
在解釋器內(nèi)部(將出現(xiàn)“>>>”),導入OpenCV庫:
如果沒有出現(xiàn)錯誤消息,則在您的PYTHON VIRTUAL ENVIRONMENT上正確安裝OpenCV。
您還可以檢查安裝的OpenCV版本:
cv2.__version__
應(yīng)該出現(xiàn)3.3.0(或者可以在將來發(fā)布的高級版本)。上述終端PrintScreen顯示前面的步驟。
一旦你在RPi中安裝了OpenCV,讓我們測試你的相機是否正常工作。
我假設(shè)您的Raspberry Pi上已經(jīng)安裝了PiCam。
在IDE上輸入以下Python代碼:
上面的代碼將捕獲將由您的PiCam生成的視頻流,以BGR顏色和灰色模式顯示它們。
請注意,由于組裝方式,我將相機垂直旋轉(zhuǎn)。如果不是您的情況,請評論或刪除“翻轉(zhuǎn)”命令行。
您也可以從我的GitHub:https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/simpleCamTest.py下載代碼
要執(zhí)行,請輸入命令:
python simpleCamTest.py
要完成程序,您必須按鍵盤上的[q] [Ctrl] + [C]鍵
圖為結(jié)果。
4.使用OpenCV在Python中進行顏色檢測
我們將嘗試完成的一件事是檢測和跟蹤某個顏色對象。為此,我們必須更多地了解OpenCV如何解釋顏色。
Henri Dang用OpenCV編寫了一篇關(guān)于Python中的顏色檢測的精彩教程。
通常,我們的相機將使用RGB顏色模式,可以通過將其視為可以由紅色,綠色和藍色的三種彩色燈制成的所有可能顏色來理解。我們將在這里使用BGR(藍色,綠色,紅色)。
如上所述,對于BGR,像素由3個參數(shù)表示,藍色,綠色和紅色。每個參數(shù)的值通常為0-255(或以十六進制表示的O到FF)。例如,計算機屏幕上的純藍色像素的B值為255,G值為0,R值為0。
OpenCV與HSV(色調(diào),飽和度,值)顏色模型一起使用,它是RGB顏色模型的替代表示,由計算機圖形學研究人員在20世紀70年代設(shè)計,以更加貼近人類視覺感知顏色制作屬性的方式:
因此,如果要使用OpenCV跟蹤某種顏色,則必須使用HSV模型對其進行定義。
假設(shè)我必須跟蹤黃色物體,如上圖所示的塑料盒。易用部分是找到它的BGR元素。您可以使用任何設(shè)計程序來查找它(我使用PowerPoint)。
在我的情況下,我發(fā)現(xiàn):
藍色:71
綠色:234
紅色:213
接下來,我們必須將BGR(71,234,213)模型轉(zhuǎn)換為HSV模型,該模型將使用上限和下限范圍進行定義。為此,讓我們運行以下代碼:
您也可以從我的GitHub下載代碼:https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/bgr_hsv_converter.py
要執(zhí)行,請輸入以下命令,其中包含之前找到的BGR值作為參數(shù):
python bgr_hsv_converter.py 71 234 213
程序?qū)⒋蛴ο箢伾纳舷逻吔纭?/p>
在這種情況下:
upper bound: [44, 255, 255]
終端打印屏幕顯示結(jié)果。
最后,但并非最不重要的,讓我們看看OpenCV在確定其顏色后如何“掩蓋”我們的對象:
您也可以從我的GitHub:https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/colorDetection.py下載代碼
要執(zhí)行,請在目錄中輸入以下命令,其中包含目標對象的照片(在我的情況下:yellow_object.JPG):
python colorDetection.py
上面的圖片將顯示原始圖像(“圖像”)以及在應(yīng)用蒙版之后對象將如何顯示(“蒙版”)。
5.物體移動跟蹤
現(xiàn)在我們知道如何使用蒙版“選擇”我們的對象,讓我們使用相機實時跟蹤它的移動。為此,我將我的代碼基于Adrian Rosebrock的Ball Tracking with OpenCV教程。
我強烈建議您詳細閱讀Adrian的教程。
首先,確認您是否安裝了imutils庫。這是Adrian的OpenCV便利功能集合,可以更輕松地完成一些基本任務(wù)(如調(diào)整大小或翻轉(zhuǎn)屏幕)。如果沒有,請輸入以下命令在虛擬Python環(huán)境中安裝庫:
接下來,從我的GitHub下載代碼https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/ball_tracking.py,并使用以下命令執(zhí)行它:
python ball_traking.py
因此,您將看到類似于以下gif的內(nèi)容:
基本上,除了“視頻垂直翻轉(zhuǎn)”之外,它與Adrian的代碼相同,我用這條線:
另請注意,使用的掩碼邊界是我們在上一步中獲得的掩碼邊界。
6.測試GPIO
現(xiàn)在我們已經(jīng)使用了OpenCV的基礎(chǔ)知識,讓我們?yōu)槲覀兊腞Pi安裝一個LED并開始與我們的GPIO進行交互。
按照上面的電氣圖:LED的陰極將通過一個220歐姆的電阻連接到GPIO 21,其陽極連接到GND。
讓我們在虛擬Python環(huán)境中測試我們的LED。
請記住,在Python虛擬環(huán)境中可能沒有安裝RPi.GPIO!要解決此問題,一旦您在那里(記得確認(cv)在您的終端中),您需要使用pip將其安裝到您的虛擬環(huán)境中:
pip install RPi.GPIO
讓我們使用python腳本執(zhí)行一個簡單的測試:
此代碼將接收GPIO編號作為參數(shù),以及LED應(yīng)閃爍的頻率(以秒為單位)。LED將閃爍5次,程序?qū)⒔K止。請注意,在終止之前,我們將釋放GPIO。
因此,要執(zhí)行腳本,必須輸入?yún)?shù),LED GPIO和頻率。
例如:
python LED_simple_test.py 21 1
上述命令將每隔“1”秒閃爍5次連接到“GPIO 21”的紅色LED。
可以從我的GitHub下載文件https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/GPIO_LED_test.py
上面的終端打印屏幕顯示結(jié)果(當然您應(yīng)該確認LED閃爍。
現(xiàn)在,讓我們使用OpenCV和一些基本的GPIO。
7.識別顏色和GPIO交互
讓我們開始將我們的OpenCV代碼與GPIO交互集成。我們將從最后的OpenCV代碼開始,我們將在其上集成GPIO-RPI庫,因此我們將在相機找到彩色物體的任何時候打開紅色LED。此步驟中使用的代碼基于Adrian的優(yōu)秀教程OpenCV,RPi.GPIO和Raspberry Pi上的GPIO Zero:
首先要做的是“創(chuàng)建”我們的LED,將其連接到特定的GPIO:
其次,我們必須初始化我們的LED(關(guān)閉):
GPIO.output(redLed, GPIO.LOW)ledOn = False
現(xiàn)在,在循環(huán)內(nèi)部,當找到對象時創(chuàng)建“圓圈”,我們將打開LED:
讓我們從我的GitHub下載完整的代碼:
https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/object_detection_LED.py
使用以下命令運行代碼:
python object_detection_LED.py
結(jié)果如下。請注意,每次檢測到物體時,LED(左下角)都會亮起:
嘗試使用不同的對象(顏色和格式)。您將看到,一旦掩模邊界內(nèi)的顏色匹配,LED就會亮起。
以下視頻顯示了一些經(jīng)驗。請注意,只會檢測到位于顏色范圍內(nèi)的黃色物體,從而打開LED。忽略具有不同顏色的對象。
我們只在這里使用LED,如上一步所述。當我拍攝視頻時,我的Pan Tilt已經(jīng)組裝完畢,所以請忽略它。我們將在下一步處理PAN / TILT機制。
8.泛傾斜機制
現(xiàn)在我們已經(jīng)使用了OpenCV和GPIO的基礎(chǔ)知識,讓我們安裝我們的Pan / tilt機制。
伺服電機應(yīng)連接到外部5V電源,其數(shù)據(jù)引腳(在我的情況下,它們的黃色接線)連接到Raspberry Pi GPIO,如下所示:
GPIO 17 ==>傾斜伺服
GPIO 27 ==> Pan Servo
不要忘記將GND連接在一起==> Raspberry Pi - Servos - 外部電源)
您可以選擇在Raspberry Pi GPIO和服務(wù)器數(shù)據(jù)輸入引腳之間串聯(lián)一個1K歐姆的電阻。這可以在發(fā)生伺服問題時保護您的RPi。
讓我們也利用這個機會,在我們的虛擬Python環(huán)境中測試我們的伺服器。
讓我們使用Python腳本用我們的驅(qū)動程序執(zhí)行一些測試:
上面代碼的核心是函數(shù)setServoAngle(伺服,角度)。該功能接收伺服GPIO編號作為參數(shù),以及伺服必須定位的角度值。一旦此函數(shù)的輸入為“角度”,我們必須將其轉(zhuǎn)換為等效的占空比。
要執(zhí)行腳本,必須輸入?yún)?shù),伺服GPIO和角度。
例如:
python angleServoCtrl.py 17 45
上述命令將連接在GPIO 17上的伺服(“傾斜”)與“仰角”成45度。
文件
https://github.com/Mjrovai/OpenCV-Object-Face-Tracking/blob/master/angleServoCtrl.py
可以從我的GitHub下載
9.查找對象實時位置
這里的想法是使用平移/傾斜機制將對象定位在屏幕中間。壞消息是,為了開始我們必須實時知道對象的位置。但好消息是,一旦我們已經(jīng)擁有了對象中心的坐標,這很容易。
首先,讓我們使用之前使用的“object_detect_LED”代碼并修改它以打印已創(chuàng)建對象的x,y坐標。
從我的GitHub下載代碼:objectDetectCoord.py
代碼的“核心”是我們找到對象并在其上繪制一個圓圈的部分,其中心有一個紅點。
讓我們將中心坐標“導出”到mapObjectPosition(int(x),int(y))函數(shù)以打印其坐標。功能下方:
def mapObjectPosition (x, y): print ('[INFO] Object Center coordinates at \ X0 = {0} and Y0 = {1}'.format(x, y))
運行程序,我們將在終端上看到(x,y)位置坐標,如上所示。移動對象并觀察坐標。我們將意識到x從0到500(從左到右),y從o到350(從上到下)。見上圖。
現(xiàn)在我們必須使用這些坐標作為我們的Pan / Tilt跟蹤系統(tǒng)的起點
10.物體位置跟蹤系統(tǒng)
我們希望我們的對象始終以屏幕為中心。所以,讓我們定義一個例子,如果符合以下情況我們會認為我們的對象是“居中的”:
220 <x <280
160 <y <210
在這些邊界之外,我們必須移動我們的Pan / Tilt機制以補償偏差?;诖耍覀兛梢詷?gòu)建函數(shù)mapServoPosition(x,y),如下所示。請注意,此函數(shù)中用作參數(shù)的“x”和“y”與我們之前用于打印中心位置的參數(shù)相同:
基于(x,y)坐標,使用函數(shù)positionServo(伺服,角度)生成伺服位置命令。例如,假設(shè)y位置是“50”,這意味著我們的對象幾乎位于屏幕的頂部,可以轉(zhuǎn)換為“相機視線”為“低”(假設(shè)傾角為120度) 所以我們必須“減少”傾斜角度(讓我們說100度),所以相機視線將“向上”并且物體將在屏幕上“向下”(y將增加,比方說,190)。
上圖顯示了幾何方面的示例。
想想泛相機將如何操作。請注意,屏幕沒有鏡像,這意味著如果您將對象移動到“左側(cè)”,一旦您與相機相反,它將在屏幕上移動“右側(cè)”。
函數(shù)positionServo(伺服,角度)可寫為:
def positionServo (servo, angle): os.system('python angleServoCtrl.py ' + str(servo) + ' ' + str(angle)) print('[INFO] Positioning servo at GPIO {0} to {1} \ degrees\n'.format(servo, angle))
我們將調(diào)用之前顯示的腳本進行伺服定位。
請注意,angleServoCtrl.py必須與objectDetectTrac.py位于同一目錄中
完整的代碼可以從我的GitHub:objectDetectTrack.py下載
下面的gif顯示了我們項目工作的一個例子:
11.結(jié)論
一如既往,我希望這個項目可以幫助其他人進入激動人心的電子世界!
聯(lián)系客服