APP 遙控教學遠端遙控
左邊的搖桿可以控制機器小車的運動。右側的按鈕可以控制攝像頭平台。
右上角的有可滑動的圖標控制【Remote Control】和【Identification & Control】的移動速度。避障 & 循跡
Sensor status display:顯示左右紅外線感測器的超聲波距離和狀態。
提示:紅外線感測器只能在【Avoid & Follow】界面開啟,一般是關閉的。
Ultrasonic avoid:Raspbot 透過超聲波模組實現避障功能。再次點擊該按鈕可關閉此功能。
Ultrasonic + IR avoid:Raspbot 透過超聲波模組和紅外線感測器同時完成避障功能。再次點擊該按鈕可關閉此功能。循跡模式
Sensor status display:顯示循跡模組 S1-S4 指示燈的狀態。檢測到黑色時,指示燈亮;否則,指示燈熄滅。
Tracking:Raspbot 完成地圖上的循跡功能,白底黑線。再次點擊該按鈕可關閉此功能。
Restricting:限制小車在白底黑線範圍內移動。再次點擊該按鈕可關閉此功能。目標偵測
人臉偵測:點擊【Face detection】按鈕,啟動人臉辨識功能。再次點擊該按鈕可關閉此功能。
顏色偵測:點擊【Color detection】按鈕啟動顏色辨識功能。支援紅、綠、藍、黃四種顏色。再次點擊該按鈕可關閉該功能。
移動偵測:點擊【Motion detection】按鈕,影片畫面中間會出現一個藍框。當這個框架中的物體移動時,藍色框架也會隨著物體移動。再次點擊該按鈕可關閉該功能。目標追蹤
人臉追蹤:點擊【Face Tracking】按鈕,將人臉對準攝像頭,緩慢移動人臉,攝像頭平台會追隨人臉移動。再次點擊該按鈕可關閉該功能。
顏色追踪:選擇顏色按鈕。然後點擊【Color tracking】按鈕,將物體(識別顏色)對準 攝像頭並緩慢移動,攝像頭平台將追隨物體移動(識別顏色)。再次點擊該按鈕可關閉該功能。
顏色跟進:將小車放在地上,點擊要跟進的顏色按鈕,點擊【Color following】按鈕。將物體(具有可識別顏色) 對準相機並緩慢移動。汽車會慢慢接近物體(識別顏色),攝像頭平台會追隨物體(識別顏色)。目標辨識
二維碼識別:點擊【QR Code Recognition】按鈕,將要識別的二維碼對準攝像頭。二維碼會出現在螢幕中,並顯示相應的字符。再次點擊該按鈕可關閉此功能。
物體識別:點擊【Object Recognition】按鈕,將要識別的物體對準攝像頭。該物體會在螢幕中被選中,並顯示相應的英文名稱字符。再次點擊該按鈕可關閉此功能。
手勢識別:在使用此功能前,需要確保您的小車連接的 WIFI 可以上網。點擊【Gesture recognition】按鈕,將手指向相機並做出手勢。識別出的手勢名稱將顯示在螢幕上。再次點擊該按鈕可關閉此功能。辨認 & 操控
二維碼控制:點擊【QR code control】按鈕,透過運行指令選擇對應的動作,點擊【Preview】按鈕生成對應的二維碼。將二維碼對準攝像頭,小車識別後會完成相應的動作。再次點擊該按鈕可關閉此功能。
手勢控制:點擊【Gesture control】按鈕,透過動作指令選擇對應的動作,點擊【Preview】按鈕查看對應的手勢。對著攝像頭做手勢,識別後小車會完成相應的動作。再次點擊該按鈕可關閉此功能。自動駕駛
點擊【Switch】可切換三種模式畫面:正常畫面、透視變換畫面、加工線歸一化處理畫面。
進入自動駕駛界面後,相機平台會移動到預設位置。我們可以調整攝像頭平台的位置,確保螢幕中的藍色線框位於車前。然後點擊自動駕駛開關打開該功能。 IR 操控教學
注意:
1、為避免陽光對紅外線感測器的干擾,必須在室內進行實驗。
2、遙控時,紅外線遙控器需要對準擴充板上的紅外線接收器。
3、在此之前,需要關閉 APP 控制。
關於紅外控制器:
運行編碼
準備工作
APP 遠端控制程序在我們提供的圖片中已經預設開啟。
如需單獨運行其它程序,請關閉 APP 遠端控制流程如下
1. 輸入命令查看 APP 遠端控制程序:ps -ef|grep python
2. 你會看到 raspbot .py 的兩個進程號,例如我的進程號是 692。
每個人的進程號都不一樣。
如下圖所示:3. 輸入命令砍掉 raspbot .py 進程:sudo kill 692
4. 然後再次輸入 ps -ef|grep python。 可以看到兩個 raspbot .py 進程消失了。
5. 現在可以正常運行其它代碼了。
在 JupyterLab 上執行一段編碼
使小車和電腦在同一個網域中。
1、如果小車透過 WIFI 連接到與 PC 相同的網路,我們可以直接在電腦端登入 Chrome 或其它瀏覽器(Raspblock IP 位址):8888 登入 Raspblock 的 JupyterLab。
例如: http: //192.168.1.244 :8888
192.168.1.244 是我的 Raspblock 小車 IP 位址。您需要輸入自己的 IP 位址。
如下所示:2、輸入密碼。如果您使用我們提供的圖檔,密碼是 yahboom。3、您會看到以下介面。4、需要進入 Yahboom_Project 目錄。5、你會看到一些目錄,你可以進入這個目錄,查看代碼。6、您可以點擊上方選單中的運行按鈕來執行程序。7、如果你想退出這個程序並運行另一個程序,需要點擊下圖所示,並打開另一個程序文件。
OpenCV基礎課程
一、OpenCV 入門
介紹
OpenCV 的全名是「Open Source Computer Vision Library」,如上圖所示,是 OpenCV的標誌。可以看到它是由三個基色R、G、B 的小環組成的。OpenCV 是一套關於計算機視覺的開源 API 函數庫。
特色: 無論是科學研究還是商業應用,都可以用於開發;
所有API函數的源代碼都是公開的,可以看到它的內部程序;
可以修改OpenCV的源代碼,編譯生成自己需要的具體API函數。
OpenCV 圖像讀取與顯示
讀取圖像:
img = cv2.imread('yahboom.jpg', 0) 第一個參數是圖片的路徑,第二個參數是如何讀取圖片。
cv2.IMREAD_UNCHANGED :保持原格式,可用參數-1表示;
cv2.IMREAD_COLOR :灰度讀取圖片,可用參數0表示;
cv2.IMREAD_GRAYSCALE :以彩色方式讀取圖片,可用1表示,默認值;
cv2.IMREAD_UNCHANGED:讀取圖片並包含其alpha通道,可用2表示。
顯示圖像:
代碼路徑home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/01Getting_started/OpenCV/01_OpenCV_image_read_display.ipynb
OpenCV 圖像寫入
第一個參數是保存文件的名稱,第二個參數是保存的圖像。
接下來,我們將演示圖像寫入的方法。首先,我們需要讀取一個圖像 yahboom.jpg,然後將其寫入 yahboom1.jpg。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/01Getting_started/OpenCV/02_OpenCV_image_write.ipynb
注意:jupyLab 中的 cv2.imshow('yahboom,img) 函數無法執行。如果需要用這句話來顯示讀取的圖像,需要在樹莓派圖形界面通過命令執行python文件。
命令: python3 XX.py
OpenCV 圖像畫素
代碼路徑:home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/01Getting_started/OpenCV/03_OpenCV_image_quality.ipynb壓縮方式
cv2.imwrite('yahboomTest.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 50])
cv2.CV_IMWRITE_JPEG_QUALITY :設定圖片(.jpeg 或 .jpg)畫素,取值範圍為 0--100(數值越大,畫質越高)。默認值為 95
cv2.CV_IMWRITE_WEBP_QUALITY :設定圖片(.web)畫素,取值範圍0--100(數值越大,畫素越高)。
cv2.CV_IMWRITE_PNG_COMPRESSION :設定圖片(.png)畫素,取值範圍為 0--100(數值越大,壓縮比越高)。默認值為 3。
OpenCV 像素操作
我們可以在圖片的任一位置更改像素顏色。首先需要讀取圖像,然後將區域分配給白色。
代碼路徑
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/01Getting_started/OpenCV/04_OpenCV_pixel_operation.ipynb
使用 JupyterLab 顯示處理前後的兩張圖像進行比較:
二、OpenCV 幾何變換
圖片縮放
在OpenCV中,實現圖片縮放的功能:
cv2.resize(InputArray src,OutputArray dst,大小,fx,fy,插值)
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course /02Geometric _ transformation/01 _picture_zoom .ipynb
內插函數選項使用的插值方法:
INTER_NEAREST 最近鄰插值
INTER_LINEAR 雙線性插值(預設)
INTER_AREA 利用像素區域關係完成對重採樣
INTER_CUBIC 4x4像素鄰域的雙三次插值
INTER_LANCZOS4 8x8 像素鄰域的 Lanczos 插值
尺寸格式:(寬、高)
預設內插方式:雙線性內插值程序執行後,可以看到圖片是 800*800,如下圖: 程序執行後,可以看到圖片是 400*400,zoom 1/2 如下圖: 接下來將介紹 matplotlib:Python 的 2D 繪圖庫
教案參考:https://www.runoob.com/numpy/numpy-matplotlib.html
圖片剪裁
如果要裁切圖片。首先需要讀取圖像,從中獲取數組中的像素區域。
在下面的代碼中,我們選擇的區域範圍是 X:300-500 / Y:500-700,
因為圖片大小是800*800,所以選擇的區域不要超過這個分辨率。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course / 02Geometric_transformation / 02_picture_cut .ipynb _ _
運行以下程序後,jupyterLab 控制介面會顯示兩張圖片,分別是原圖和裁切圖。
圖片移位
通過轉換矩陣 M 將原始圖像 src 轉換為目標圖像 dst:
dst(x, y) = src(M11x + M12y+M13, M21x+M22y+M23)
將原圖 src 向右移動 200 像素,向下移動 100 像素,對應關係為:
dst(x, y) = src(x+200, y+100)
根據公式完成上面的表達式。
dst(x, y) = src(1·x + 0·y + 200, 0·x + 1·y + 100)
根據上面的表達式,我們可以確定對應的轉換矩陣M中每個元素的值。
M11=1
M12=0
M13=200
M21=0
M22=1
M23=100
將上述值代入變換矩陣 M,我們可以得到 M = []
接下來我們直接使用轉換矩陣 M 調用函數 cv2.warpAffine() 來完成圖像的平移。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course /02幾何_變換/ 03_圖片_ shift .ipynb
運行以下程序後,jupyterLab 控制介面會顯示兩張圖片,分別是原圖和切換後的圖。
根據上圖,這張圖已經移到了右下角(200,100) 圖片鏡像
圖片鏡像變換有兩種類型:水平鏡像和垂直鏡像。
水平鏡像是以圖片的垂直中心線為軸來交換圖片的像素,即交換圖片的左半邊和右半邊。
垂直鏡像以圖像的水平中心線為軸,將圖像的上半部分與下半部分互換。
改造原理:
設定圖像的寬度為寬度,長度為高度。(x, y) 是變換後的坐標,(x0, y0) 是原始圖片的坐標。
水平鏡像變換逆變換垂直鏡面變換逆變換我們以垂直變換為例
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV _course / 02幾何_變換/04_Picture_mirroring.ipynb _
仿射圖
仿射變換(Affine Map)是從二維坐標(x,y)到二維坐標(u,v)的線性變換。
其數學表達式如下,
對應的齊次坐標矩陣數學表達式如下仿射變換保留了二維圖形的「直線性」和「平行性」。
直線度:仿射變換後的直線將維持直線。
平行度:仿射變換後平行線維持平行,直線上所有點的位置順序不變,兩條直線的相對位置關係不變。
非共線的三對對應點可以確定一個仿射變換。
精細變換 = 圖片 旋轉 + 圖片提升。
仿射變換也需要一個 M 矩陣。由於仿射變換的複雜性,很難找到這個矩陣。OpenCV可以根據變換前後三點的對應關係自動求解矩陣M。
M = cv2.getAffineTransform (pos1, pos2),pos1和pos2是變換前後對應的位置關係。
輸出是仿射矩陣 M。
然後可以使用函數 cv2.warpAffine ()。
兩種圖像變換方法 cv2.warpAffine 和 cv2.warpPerspective
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course /02幾何_變換/ 05_ Affine_Map .ipynb
圖片旋轉
圖像旋轉是圖像根據一定位置旋轉到一定角度的過程。在旋轉過程中,圖像仍保持其原始大小。
旋轉後的圖像,可以對其水平對稱軸、垂直對稱軸和中心坐標原點進行變換。因此,我們需要對圖像旋轉中的坐標進行相應的變換。
坐標變換圖如下所示:如果圖像逆時針旋轉θ。根據坐標轉換圖,旋轉轉換後x軸和y軸的位置為,
1. 和 2. 將第2式代入第1式,可得計算後:由於旋轉後圖片的灰度值等於原圖片中相應位置的灰度值,我們可以得到如下數學表達式: f(x',y')=f(x,y)
以上就是旋轉的原理。
OpenCV提供了一個函數,可以直接通過函數獲取轉換矩陣。功能如下,
matRotate = cv2.getRotationMatrix2D(中心,角度,比例) - center:旋轉的中心點
- angle:旋轉的角度。正數表示逆時針;負數表示順時針
- scale:變換比例(縮放大小)。1表示無變化,<1表示縮小,>1表示放大。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course /02幾何_變換/ 06_Picture_R otation.ipynb
運行以下程序後,jupyterLab控制界面會顯示兩張圖片,分別是原始圖片和旋轉後的圖片。
運行以下程序後,jupyterLab控制界面會顯示兩張圖片,如下圖: 透視變換
透視變換也稱為投影變換。透視變換的目的是通過透視變換將現實中是直線但在圖片上可能表現為斜線的物體變換成直線。
透視變換可以將矩形映射到任意四邊形。我們將在我們的機器人 Autopilot 課程中使用這種技術。
透視變換函數:
dst = cv2。warpPerspective(src, M, dsize[,flag, [,borderMode[,borderValue]]])
- dst:透視變換後的輸出圖片,dsize決定了輸出圖片的實際大小。
- src:源圖片(原圖)
- M:3x3變換矩陣
- dsize:輸出圖像的大小
- Flags:插值方式,默認INTER_LINEAR(雙線性插值),當為WARP_INVERSE_MAP時,表示M為逆變換,可以實現目標dst到src的逆變換。
- borderMode:邊緣類型。默認值為 BORDER_CONSTANT。當值為 BORDER_TRANSPARENT 時,表示目標圖像中的值沒有變化,這些值對應於原始圖像中的異常值。
- borderValue:邊框值,預設為0。
OpenCV 提供了一個函數來為透視變換提供變換矩陣。
功能如下:
matAffine = cv2.getPerspectiveTransform(matSrc, matDst)
- matSrc:輸入圖片四個頂點的坐標。
- matDst:輸出圖片四個頂點的坐標。
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV_course/02Geometric_transformation/ 07_Perspective_transformation.ipynb
三、OpenCV 圖片處理
灰度處理
將彩色圖片轉換為黑白圖片的過程就是圖片的灰度處理。彩色圖像中彩色圖片的每個像素由 R、G、B 三個分量決定,每個分量範圍為 0-255,因此一個像素可以有超過1600萬(256*256*256 = 1677256)種顏色。
黑白圖像是 R、G、B三個分量相同的特殊彩色圖像,一個像素的範圍是256種。
因此,在數字圖像處理中,我們會將各種格式的圖像轉換為黑白圖像,以減少計算量。
黑白圖像仍然可以反映圖片的色度和亮度級別的整體和部分分佈。
黑白圖像的描述與彩色圖像一樣,仍然反映了整個圖像的整體和局部色度和光線水平的分佈和特徵。
圖像變灰
灰度處理是將彩色圖像轉換為黑白圖像的過程。彩色圖像分為R、G、B三個分量,顯示紅、綠、藍等各種顏色。灰度值較大的像素更亮(最大像素值為 255,白色),灰度值較小的像素更暗(最小像素值為 0,黑色)。
圖像黑白化的核心思想是 R=G=B,這個值也叫灰度值
圖像灰度化算法
1)最大值法:使 R、G、B 轉換後的值等於轉換前三個值中的最大值,即:R=G=B=max(R,G,B)。這種方法轉換後的黑白圖像亮度非常高。
2)平均法:換算後的 R、G、B 值為換算前 R、G、B 的平均值。即:R=G=B=(R+G+B)/3。這種方法產生的黑白圖像比較柔和。
3)加權平均法:根據一定的權重,將 R、G、B 的值加權平均,即 R、G、B 的權重。我們可以取不同的值,形成不同的黑白圖像. 由於人眼對綠色、紅色最敏感,而對藍色的敏感度最低,這種方可以產生最好的黑白圖像。
下面的代碼包含四種對圖片進行灰度化的方法,
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course /0 3IP_Draw_text_line_segments / 06_ Picture_R otation.ipynb
運行以下程序後,jupyterLab 控制介面會顯示黑白圖片,如下圖: 運行以下程序後,jupyterLab 控制介面會顯示黑白圖片,如下圖: 運行以下程序後,jupyterLab 控制介面會顯示黑白圖片,如下圖: 運行以下程序後,jupyterLab 控制介面會顯示黑白圖片,如下圖:
圖像二值化
對於二值化,我們需要設置一個門檻值(閾值)。 大於門檻值的為0(黑色)或255(白色),圖片稱為黑白圖片。 門檻值可以是固定的,也可以是自適應門檻值。
一般情況下,自適應門檻值是該區域內像素按此順序排列的平均值之比或高斯分佈與該點像素的加權和。
全局閾值
Python-OpenCV 提供閾值函數:
cv2.threshold(src, threshold, maxValue, method)
src 原圖:折線是要閾值的值; 虛線是閾值。cv2.THRESH_BINARY:設置灰度值大於閾值的像素點的灰度值為maxValue(例如最大8位灰度值為255),設置灰度值為的像素點的灰度值小於0的閾值。cv2.THRESH_BINARY_INV:設置大於閾值的像素灰度值為0,小於閾值的像素灰度值為maxValue。cv2.THRESH_TRUNC:如果像素的灰度值小於閾值,則保持不變; 如果像素的灰度值大於閾值的灰度值,則將灰度值的像素設置為閾值。cv2.THRESH_TOZERO:如果像素的灰度值小於閾值,則保持不變; 如果像素的灰度值大於閾值,我們需要將所有灰度值設置為0。cv2.THRESH_TOZERO_INV:如果像素的灰度值大於閾值,則保持不變; 如果像素的灰度值小於閾值,我們需要將其灰度值設置為0。代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV_course/03IP_Draw_text_line_segments/ 02Image_Binarization.ipynb
運行以下程序後,jupyterLab控制界面會顯示二值化圖片,如下圖。 邊緣檢測
邊緣檢測的目的是在保留原始圖像屬性的同時顯著減小圖像數據量。
Canny邊緣檢測是從不同的視覺對像中提取有用的結構信息,可以大大減少需要處理的數據量。它已廣泛應用於各種計算機視覺系統。
邊緣檢測的標準:
以低錯誤率檢測邊緣。
檢測到的邊緣應準確定位在實際邊緣的中心。
圖像中給定的邊緣只應標記一次,圖像的噪聲不應產生虛假邊緣。
Canny邊緣檢測算法可以分為以下5個步驟:
1)使用高斯濾波器對圖像進行平滑並濾除噪聲。
2)計算圖像中每個像素點的梯度強度和方向。
3)應用非最大抑制來消除邊緣檢測引起的雜散響應。
4)應用雙閾值檢測來確定真實邊緣和潛在邊緣。
5)通過抑制孤立的弱邊緣來完成邊緣檢測。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course / 0 3IP_Draw_text_line_segments / 03_1edge _ detection1.ipynb
兩張對比圖
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV _course /03 IP_Draw_text_line_segments 03_2edge _ detection2.ipynb
運行以下程序後,jupyterLab控制界面會顯示二值化圖片,如下圖。 畫線段
在使用OpenCV處理圖像時,有時我們需要在圖像上繪製線段、矩形等。OpenCV 使用函數 line (dst, pt1, pt2, color, thickness = None, lineType = None, shift = None) 來繪製線段。
參數說明
dst:輸出圖像。
pt1、pt2:必填參數,pt1為起點,pt2為終點。
color:必選參數,用於設置線段的顏色。
粗細:可選參數,用於設置線段的粗細。
lineType:可選參數,用於設置線段的類型,8(8相鄰連接線-默認),4(4相鄰連接線)和cv2.LINE_AA抗鋸齒
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV _course / 0 3IP_Draw_text_line_segments / 04_畫線段.ipynb
運行以下程序後,jupyterLab控制界面會顯示一張圖片,如下圖。
畫矩形圖
1. 繪製矩形
矩形(img , pt1 , pt2 , color ,粗細=None , lineType=None , shift=None )
參數說明
- img:畫布或載體圖像。
- pt1、pt2 :必填參數。表示頂點和對角頂點,即矩形的左上角和右下角。
- color:必填參數,用於設置矩形的顏色。
- 厚度:可選參數,用於設置矩形邊的寬度,值為負數時,表示填充矩形。
- lineType :可選參數,用於設置線段的類型,8(8相鄰連接線-默認)、4(4相鄰連接線)和cv2.LINE_AA抗鋸齒。
2. 畫圈
cv2.circle(img, center, radius, color[,thickness[,lineType]])
參數說明
- img:畫布或載體圖像
- center:圓心坐標,格式:(50,50)
- 半徑:半徑
- 顏色:彩色
- 厚度:用於設置圓邊的寬度,值為-1時表示填充圓。
- lineType:線段的類型。默認為8,連接類型說明如下表所示。
範圍 | 描述 |
cv2.FILLED | 填滿 |
cv2.LINE_4 | 4 連接 |
cv2.LINE_8 | 8 連接 |
cv2.LINE_AA | 消鋸齒,讓線條更平滑 |
3. 畫橢圓
cv2.ellipse(img, 中心, 軸, 角度, StartAngle, endAngle, color[,thickness[,lineType]])
參數說明- center:橢圓的中心點(x, x)
- 軸:短半徑和長半徑,(x, x)
- angle:逆時針旋轉的角度
- StartAngle:圓弧起始角的角度
- endAngle:圓弧結束角的角度
- Img, color:畫布或載體圖像和顏色。
# 第五個參數是逆時針開始繪製的角度,第六個參數是逆時針結束繪製的角度
# 如果第四個或第五個參數加符號,則表示相反的方向,即順時針方向。
4. 繪製多邊形
cv2.polylines(img,[pts],isClosed, color[,thickness[,lineType]])- pts:多邊形的頂點
- isClosed:是否關閉。(真假)
- 其他參數參考畫圓參數
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course / 0 3IP_Draw_text_line_segments / 05_繪製矩形_圓形.ipynb 運行以下程序後,jupyterLab控制界面會顯示一張圖片,如下圖。
繪製文字圖片
功能: cv2.putText(img, str, origin, font, size,color,thickness)
參數有:圖片、需要添加的文字、左上角坐標(整數)、字體、字體大小、顏色、字體粗細。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/03IP_Draw_text_line_segments/ 06_Drawing text picture.ipynb
運行以下程序後,jupyterLab 控制介面會顯示如下圖。
四、OpenCV 圖像美化
彩色圖片直方圖
顏色直方圖是指圖像中的顏色分佈。
圖片中每個像素的顏色值可以用一個三元值(R,G,B)來表示,例如(0,0,0)表示黑色,(0,0,255)表示藍色,每個分量範圍的大小為 0 ~ 255。
將R、G、B三個通道疊加起來就可以形成一幅彩色圖像。我們可以想像將三張同樣大小的紙疊起來,然後從上往下看。您看到的圖像是原始彩色圖像。
例如,如果圖像的分辨率為 320 * 240,那麼每個通道的長度為 320,寬度為 240,單位為像素。總像素數為 3 * 320 * 240。
方法 一:
我們可以使用matplotlib的子庫pyplot,它提供了一個類似於Matlab的繪圖框架,matplotlib是一個Python繪圖包。繪製直方圖主要是通過調用 hist() 函數來實現的,該函數會根據數據源和像素級別繪製直方圖。
hist()函數的形式:hist(數據源,像素級)
參數說明:
- 數據來源:一維數組,需要通過函數ravel()把圖片拉直
- 像素級別:256,表示[0, 255]
ravel() 用於將多維數組縮減為一維數組。
ravel()函數的形式 :One-dimensional array = multi-dimensional array.ravel ()
例如:plt.hist(img.ravel(), 256)
#ravel() 二維轉一維256灰度分組
方法二:
OpenCV 提供以下功能。
cv2.calcHist(image,channels,mask,histSize,ranges[,hist[,accumulate]])
參數說明:
- 圖片:輸入圖片,需用括號[]括起來
- channels:傳入圖像的通道,如果是灰度圖像,只有一個通道,值為0。如果是彩色圖像,有3個通道,值為0,1,2,我們可以選擇此值之一,應將其括在括號 [] 中
- mask:蒙版圖像。如果算上整張圖,那就沒有了。如果計算零件圖,則需要構造相應的炎症掩碼進行計算。
- histSize:灰度級數,需用括號[]括起來
- 範圍:像素值的範圍,範圍[0,256]。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/04image_beautification/ 01_Histogram of color pictures.ipynb 運行以下程序後,jupyterLab控制界面會顯示三張圖片,如下圖。
直方圖均衡
圖像的空間處理主要分為灰度變換和空間濾波兩大類。直方圖均衡化是一種常用的灰度變換方法。通常,暗圖像直方圖的分量集中在灰度級的低端,亮圖像直方圖的分量偏向灰度級的高端。
直方圖均衡化是對原始直方圖進行拉伸,使其在整個灰度範圍內均勻分佈,增強圖像的對比度。
函數: cv2.equalizeHist()
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/04image_beautification/ 02_Histogram_equalization.ipynb
運行以下程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。
運行以下程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。 運行以下程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。
圖像恢復
圖像恢復是計算機視覺中的一種算法,其目標是填充圖像或影片中的區域。它還用於刪除圖像中不需要的小對象。
dst = cv2.inpaint(src, inpaintMask, inpaintRadius, flags)
參數說明:
- src:原圖像(原始圖像)
- inpaintMask:表示要修復的像素的二進制掩碼。
- dst:結果圖像
- inpaintRadius:恢復半徑
- flags:恢復算法,主要包括INPAINT_NS(Navier-Stokes based method)或INPAINT_TELEA(Fast marching based method)
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/04image_beautification/03_Image_restoration.ipynb
運行以下程序後,jupyterLab控制界面會顯示一張圖片,如下圖。 運行上述程序後,jupyterLab控制界面會顯示三張圖片,如下圖。 亮度增強
實現過程:同步放大每個像素的三個通道值,同時保持通道值在0-255之間。
map (f, list)將函數 f 應用於整個列表並返回新列表。
np.clip (a, a_min, a_max, out = None) 將 a 中的元素限制為最小值和最大值
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/04image_beautification/04_Brightness_enhancement.ipynb
運行上述程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。 皮膚美白
圖片美白配方:
p = P*1.4(a)+ b
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/04image_beautification/05_Skin_whitening.ipynb
運行上述程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。雙邊濾波是一種非線性濾波方法。這種方法能更好地濾除低頻信息。
代碼如下:
運行上述程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。 高斯均值濾波
圖像處理-過濾
濾波:它是信號和圖像處理中的基本操作。目的是根據應用環境有選擇地提取圖像中認為重要的某些信息。通過過濾,我們可以去除圖像中的噪聲,提取一些視覺特徵,允許圖像重採樣等等。
頻域分析:將圖像從低頻到高頻分成不同的部分。低頻對應於圖像強度變化很小的區域。高頻對應於圖像強度變化非常大的區域。
在頻率分析的框架中,濾波用於增強圖像中的某個頻帶或頻率,並阻止(或減少)其他頻帶。
低通濾波器去除圖像的高頻部分,保留低頻部分。
高通濾波器消除了圖像的低頻部分,保留了高頻部分。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV _course / 04 i mage_beautification / 06_Gaussian _mean_filtering.ipynb _ _
運行上述程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。
中值濾波
中值濾波:圖像平滑可以消除椒鹽噪聲(脈衝雜訊)。其基本思想是通過一個過濾器對圖像進行遍歷,並將每個過濾器區域的像素值的中值作為新的像素值。
算法思路如下:
- 輸入圖像並轉換為灰度圖像;
- 在灰度圖像中加入椒鹽噪聲(脈衝雜訊);
- 遍歷像素,將過濾區域內的像素值放入一維數組中;
- 對一個一維數組進行選擇性排序,將中值賦值給濾波器的中心,即將遍歷的原始圖像的像素點變為濾波器區域的中值;
- 輸出中值濾波後的圖像。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/04image_beautification/ 07_Median_ filtering.ipynb 運行上述程序後,jupyterLab控制界面會顯示兩張圖片,如下圖。 五、OpenCV 機器學習
KNN 識別手寫數字
定義:
機器學習是一門多學科交叉學科,涵蓋概率論、統計學、近似理論和復雜算法等知識。
機器學習有以下定義:
- 機器學習是一門人工智能科學。該領域的主要研究對像是人工智能。
- 機器學習是對可以通過經驗自動改進的計算機算法的研究。
- 機器學習利用數據或過去的經驗來優化計算機程序的性能標準。
KNN(K Nearest Neighbor Algorithm)識別手寫數字
KNN的思想是,在特徵空間中,如果一個樣本中k個最近的特徵樣本中的大部分屬於某個類別,那麼該樣本也屬於該類別。
KNN的工作原理,有一個樣本數據集(訓練樣本集),樣本集中的每個數據都有一個標籤,即我們知道樣本集中的每個數據與其所屬的類別的對應關係屬於。輸入未標註數據後,將新數據中的每個特徵與樣本集中數據對應的特徵進行比較,提取樣本集中特徵最相似的數據的分類標籤。
一般來說,我們只選擇樣本數據集中前K個最相似的數據。這就是K最近鄰算法中K的來源,K是小於20的整數。最後選擇K個最相似數據出現次數最多的分類作為新數據的分類。
KNN優勢:
KNN 缺點:
- 缺乏訓練階段,無法應對多樣本
- 計算更複雜,空間更複雜
KNN實現步驟:
歐幾里得距離公式如下所示 - 按距離遞增關係排序;
- 選擇距離最小的K點(小於20點)
- 確定K點的類別出現頻率;出現頻率=類別/k
- 返回K個點中頻率最高的類別作為測試數據的預測分類。
接下來,我們以手寫數字的識別為例,簡單介紹一下KNN算法的實現。【32*32像素數據集】【文字資料】
數據集分為訓練集和測試集,其中訓練集是已經分類的數據,測試集用於測試算法。
1.識別手寫數字確定K值
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV _course /05machine_learning / 01KNN/KNN _1 .ipynb
將數據轉換為特徵向量
從上圖可以看出,我們得到了一個32*32的矩陣,每個點都是一個像素值,將這1024個(32x32)個值轉換成一個(1,1024)個向量。
KNN 分類器
輸入測試集,測試算法
選擇不同的k值查看分類效果
運行程序後,我們可以看到下圖所示的結果。實驗結果證明,取k=3效果更好。也可以嘗試其他值,但是速度很慢。
以下是用 k = 3 測試的:
運行程序後,我們可以看到下圖所示的結果。2.R識別手寫 數字
製作手寫數字圖片的步驟:
①打開繪圖軟件,調整分辨率為32*32,其他分辨率也可以,但最好是圖片能填滿整個區間,如下所示。【調整分辨率】
②按「ctrl」,鼠標滾輪向上滑動,將圖片放大到最大。選擇油漆桶工具並選擇黑色填充整個螢幕。③選擇鉛筆工具,顏色選擇白色,線條粗細選擇最大寬度。如下所示。④我們可以寫一個數字,它需要填滿整個區域。⑤繪製完成後,將其保存為png圖像,並使用WinSCP工具將其複製到專案目錄中。代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/05machine_learning/01KNN/KNN_2.ipynb代碼如下圖。 運行程序後,我們可以看到下圖所示的結果。!筆記:
如果識別結果與真實結果不同。請將轉換後的txt文件複製到knn-digits/trainingDigits/,命名為:2_201.txt,然後重新訓練,就可以正常工作了。
CNN 識別手寫數字
以下兩條分界線之間的內容,就是你在搭建自己的開發環境的過程中需要做的事情。由於環境已經搭建完成,您可以跳過本教程。
僅用於環境建設學習。
!注意,運行環境必須是 Python2 。如果系統提示,「錯誤:雲端模塊丟失」。我們可以輸入 sudo pip install cloud 進行安裝。
首先,我們需要在python2中安裝ipykernel包
輸入命令:sudo pip install ipykernel
然後,我們輸入以下命令來安裝內核。
sudo python2 -m ipykernel install --name python2
該命令中的第一個 python2 表示這是自己安裝的python版本,用來和python3區分開來。
第二個 python2 是安裝內核後jupyterlab中顯示的內核名稱(可自定義)。Tensorflow 網站: https ://www.tensorflow.org/
錯誤報告的解決 方案 : - pip 卸載 protobuf
- 點卸載谷歌
- 點安裝谷歌
- 點安裝 protobuf
- pip 卸載 setuptools
- 點安裝安裝工具
CNN的基本結構包括兩層:
- 特徵提取層。
- 特徵映射層。
在本課程中,我們將使用 LeNet-5(現代)來學習手寫數字的識別過程。輸入層
圖像大小為32×32×1,1代表黑白圖像,只有一個通道。
卷積層
濾波器大小為5×5,濾波器深度(個數)為6,padding為0,卷積步長s=1,輸出矩陣大小為28×28×6,6表示濾波器個數。
池化層
平均池化,濾波器大小 2 × 2 (f = 2),步長 s = 2,無填充,輸出矩陣大小為 14×14×6。
卷積層
濾波器大小為5×5,濾波器個數為16,padding為0,卷積步長為s=1,輸出矩陣大小為10×10×16,16代表濾波器個數。
池化層
平均池化,濾波器大小 2 × 2 ( f = 2),步長 s = 2,無填充,輸出矩陣大小為 5 × 5 × 16。
!注意,這一層的最後,5×5×16的矩陣需要被展平成一個400維的向量。
全連接層(FC)--神經元數量為 120。
全連接層(FC)--神經元數為 84。
全連接層、輸出層--該層神經元個數為10個,0~9代表十個數字類別
LeNet -5 的特性 - 如果神經網絡層數不包括輸入層,LeNet-5是一個7層網絡。
- LeNet-5擁有約60,000個參數。
- 隨著網絡越來越深,圖像的高度和寬度都在縮小。與此同時,圖像的通道數也在不斷增加。
- 目前使用的LeNet-5結構與Yann LeCun教授在1998年論文中提出的結構不同。比如激活函數的使用,使用ReLU作為激活函數,但是輸出層一般會選擇softmax。
MNIST_data
我們可以在這個網站上獲取 MNIST 數據集:http: //yann.lecun.com/exdb/mnist/
它包括四個部分。
訓練集圖片:train-images-idx3-ubyte.gz(9.9 MB,解壓後47 MB,包含60,000個樣本)
訓練集標籤:train-labels-idx1-ubyte.gz(29 KB,解壓後60 KB,包含60,000個標籤)
測試集圖片:t10k-images-idx3-ubyte.gz(1.6 MB,解壓後7.8 MB,包含10000個樣本)
測試集標籤:t10k-labels-idx1-ubyte.gz(5KB,解壓後10KB,包含10000個標籤)
TensorFlow 項目目錄: https ://github.com/tensorflow/tensorflow
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/05machine_learning/02CNN/CNN.ipynb
製作手寫數字圖片的步驟,請參考上一課。我們需要黑色和白色背景上的數字,分辨率為 28 * 28。數字必須填滿整個區域。
原圖:結果,如下圖。 SVM 識別手寫數字
SVM的過程:
① 收集數據:提供文本文件
② 準備數據:基於二值圖像構造向量
③ 分析數據:目測圖像
④訓練算法:採用兩種不同的核函數,對徑向基核函數使用不同的設置來運行SMO算法
⑤測試算法:寫一個函數來測試不同的核函數併計算錯誤率
⑥ 使用算法:支持向量機幾乎可以用於所有的分類問題。SVM 本身是一個二等分類器。將 SVM 應用於多類問題需要對代碼進行一些修改。
KNN 與 SVM
相似之處:
兩者都是比較經典的機器學習分類算法,都屬於監督學習算法。
區別:
①KNN必須考慮每個樣本。SVM就是找一個函數來劃分樣本達到。
②SVM的本質是求權重。
③KNN不能處理高維的東西,SVM可以用來處理高維的數據。
④KNN計算複雜,SVM需要訓練過程。
如何選擇兩者兼用?
1.選擇KNN場景:
2.選擇SVM場景:
- 需要提高準確率。
- 樣本很多。
- 樣本是固定的,不隨時間變化。
該項目需要安裝 Python 庫。我們提供的出廠鏡像已安裝,用戶無需再次安裝。
sudo pip install pypng
sudo pip install sklearn
sudo pip install sklearn
sudo apt-get install python-matplotlib
首先,我們需要對 MNIST 數據進行預處理,並將其轉換為 png 圖像。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/05machine_learning/03SNM/03_1.MNIST.ipynb注意:
在我們提供的圖片中,已經運行如下代碼,並生成了對應的文件。
如果需要再次運行這段代碼 ,需要刪除該目錄下的兩個文件 MSIST_data/test 和 train 。然後,再運行以下代碼。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/1.OpenCV_course/05machine_learning/03SVM/ 03_2.SVM_training model.ipynb
本次訓練過程耗時較長,大概四個小時左右,請耐心等待打印所用時間。以下時間範圍超過變量的最大值,將打印為負值,忽略警告。這是測試 MNIST 數據集的代碼。
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV_course/05machine_learning/03SVM/ 03_3.SVM_MNIST.ipynb根據上圖,我們可以看到只有數字7的識別率很高。
代碼路徑:
/home/pi/Yahboom_Project/1.OpenCV_course/05machine_learning/03SVM/03_4.SVM.ipynb
原圖:結果,如下圖。
硬體組件控制
一、蜂鳴器
學習目標
在本課程中,我們將學習如何在汽車上驅動蜂鳴器。
原理
蜂鳴器分為「有源蜂鳴器」和「無源蜂鳴器」兩種。
主動意味著它們內部擁有一個多振動器。它只需要外部提供工作電壓,就可以發出固定頻率的聲音。
無源是指沒有內部振盪源,需要外部驅動電路提供一定頻率的驅動信號。
在本實驗中,我們將使用無源蜂鳴器。
從硬件接口手冊中可以看出,蜂鳴器是由Pin 32 of Raspberry Pi直接驅動的。
編碼方式
樹莓派的PIN對照表如下圖所示。在本課程中,我們使用 BOARD 編碼方法。
我們需要在代碼中控制樹梅派板中的32個 pin
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2.Hardware Control course/1.Drive buzzer/buzzer test.ipynb
1)導入時間和RPI.GPIO庫2) 設置 GPIO 管腳編號模式為 BOARD,蜂鳴器管腳為輸出模式。創建 PWM 輸出,佔空比為 50,範圍為 0-100。3) PWM的佔空比在0-100之間切換,並保持循環在這個狀態4)當我們點擊JupyterLab菜單欄中的停止按鈕,退出循環後,停止PWM並清除GPIO。5 . 運行代碼,點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序6.實驗現象
我們會聽到蜂鳴器的哨聲。
路徑: Path: /home/pi/Yahboom_project/Raspbot/2.Hardware Control course/1.Drive buzzer/buzzer sing.ipynb1)導入時間和RPI.GPIO庫2)根據頻率列表,通過比較歌曲的編號樂譜,定義歌曲的音符和節拍列表。3) 定義初始化函數--setup 設置GPIO 為BOARD 編碼模式,設置蜂鳴器引腳為PWM 輸出。
運行函數循環根據頻率列表播放音樂。4) 調用初始化循環函數播放音樂,點擊方形停止按鈕時退出循環,清空GPIO。運行程序後,可以聽到蜂鳴器播放音樂
二、馬達
學習目標
在本課程中,我們將學習如何驅動汽車的馬達。
原理
對於 Raspbot 汽車,我們使用 4 個 TT 直流齒輪馬達。它們由 TB6612 芯片驅動。驅動芯片不直接連接樹莓派引腳。
樹莓派通過IIC與STM8 MUC通信,然後STM8 MCU驅動TB6612芯片驅動馬達。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。
STM8接樹莓派板上的SDA.1、SCL.1。
樹莓派的PIN對照表如下圖。
我們提供了一個專門用於馬達和伺服系統的庫文本——YB_Pcb_Car.py。
它與電機驅動器位於同一目錄中。
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2. Hardware Control course / 2.Drive motor
1)導入時間和YB_Pcb_Car庫2)控制小車以150的速度前進兩秒(速度範圍:0~255)。3) 以150的速度控制小車後退兩秒(速度範圍:0~255)。4) 停車5) 使用完後需要釋放car對象,否則下次程序需要使用該對象時,會因為被佔用而無法使用。
運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
汽車會完成一些動作。
三、伺服馬達
學習目標
在本課程中,我們將學習如何驅動汽車的伺服。
原理
在 Raspbot 小車的驅動板上,我們集成了 4 個伺服管腳接口,分別位於下圖(S1~S4)的位置。舵機的驅動芯片 TB6612 不直接接樹莓派管腳。
樹莓派通過IIC與STM8 MCU通信,STM8 MCU驅動TB6612芯片驅動舵機。
伺服接線:
舵機的棕色線需要連接到擴展板上標有“-”的引腳。
舵機的紅線需要連接到擴展板上標有“+”的引腳。
舵機的橙色線需要連接到擴展板上標有“IO”的引腳。
Raspbot 車載攝像頭平台有兩個舵機,分別連接到 S1 和 S2 端口。
編碼方式
STM8接樹莓派板上的SDA.1、SCL.1。
樹莓派的管腳對照表如下圖。在本課程中,我們使用 BOARD 編碼方法。
我們提供了一個專門用於驅動電機和伺服系統的庫文本——YB_Pcb_Car.py。
它與電機驅動器位於同一目錄中。
關於代碼
路徑:/home/pi/Yahboom_project/Raspbot/2.Hardware Control course/2.Drive servo1)導入時間和YB_Pcb_Car庫2)控制兩個舵機移動到中間位置(90°)。3)控制兩個舵機移動到中間位置(0°)。4)控制兩個舵機移動到中間位置(180°)。5) 使用完後需要釋放car對象,否則下次程序需要使用該對象時,會因為被佔用而無法使用。
運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
兩個舵機將旋轉到90°--> 0°--> 180°。
四、超聲波範圍
學習目標
在本課程中,我們將學習如何使用超聲波測距。
實驗原理
超聲波模塊是一種利用超聲波特性來檢測距離的感測器。它有兩個用於發射和接收超聲波的超聲波探頭。測量範圍為 3-450 厘米。(1) 需要向Trig 管腳輸入至少10us 的高電平信號,才能觸發超聲波模塊的測距功能。(2)測距功能觸發後,模塊會自動發出8個40kHz的超聲波脈衝,並自動檢測是否有信號返回。此步驟由模塊內部完成。(3) 當模塊檢測到回波信號時,ECHO 管腳會輸出高電平。高電平持續時間是超聲波從發出到返回的時間。您可以通過使用時間函數計算高電平持續時間來計算距離。
公式:距離=高電平持續時間*音速(340M/S)/2。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。
根據硬件接口手冊,我們看到超聲波 Echo 和 Trig 引腳連接到樹莓派板的 18 和 16 引腳。
樹莓派的管腳對照表如下圖。
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2.Hardware Control course/5.Ultrasonic avoid/Ultrasonic avoid.ipynb1)導入時間和GPIO庫2) 忽略警告3)定義超聲波模塊的引腳4)設置管腳的編碼方式,設置Echo和Trig管腳的模式5)定義超聲波測距功能
我們需要給超聲波模塊的TRIG管腳設置一個至少10us的高電平信號來觸發模塊的測距功能。
運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
程序運行後,我們可以看到 JupyterLab 上會打印出距離。
五、超聲波避障
學習目標
在本課程中,我們將學習如何使用超聲波模塊完成避障實驗。
實驗原理
超聲波模塊是一種利用超聲波特性來檢測距離的感測器。它有兩個用於發射和接收超聲波的超聲波探頭。測量範圍為 3-450 厘米。(1) 需要向Trig 管腳輸入至少10us 的高電平信號,才能觸發超聲波模塊的測距功能。(2)測距功能觸發後,模塊會自動發出8個40kHz的超聲波脈衝,並自動檢測是否有信號返回。此步驟由模塊內部完成。(3) 當模塊檢測到回波信號時,ECHO 管腳會輸出高電平。高電平持續時間是超聲波從發出到返回的時間。您可以通過使用時間函數計算高電平持續時間來計算距離。
公式:距離=高電平持續時間*音速(340M/S)/2。
對於 Raspbot 汽車,我們使用 4 個 TT 直流齒輪電機。它們由 TB6612 芯片驅動。驅動芯片不直接連接樹莓派引腳。
樹莓派通過IIC與STM8 MUC通信,然後STM8 MCU驅動TB6612芯片驅動電機。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。
根據硬件接口手冊,我們看到超聲波 Echo 和 Trig 引腳連接到樹莓派板的 18 和 16 引腳。
STM8接樹莓派板上的SDA.1、SCL.1。
我們提供了一個專門用於馬達和伺服系統的庫文本——YB_Pcb_Car.py。
樹莓派的管腳對照表如下圖。
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2. Hardware Control course / 5.Ultrasonic Avoid/ Ultrasonic Avoid.ipynb
1)導入時間、GPIO和YB_Pcb_Car庫2)設置GPIO編碼模式,定義超聲波模塊引腳,定義汽車類用於馬達或舵機。
3)定義超聲波測距功能
我們需要給超聲波模塊的TRIG管腳設置一個至少10us的高電平信號來觸發模塊的測距功能。4) 定義超聲波測距優化程序,優化測試結果。5)定義避障功能,完成小車的超聲波避障功能。6) 循環調用避障函數,完成避障實驗。當我們點擊停止按鈕時,我們退出循環,停止汽車,並清除汽車類和 GPIO。 運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
程序運行後,我們可以看到小車會向前行駛,遇到前方障礙物時會避開障礙物。
六、超聲波+IR紅外線避障
學習目標
在本課程中,我們將學習如何使用超聲波模塊和紅外避障傳感器完成避障實驗。
實驗原理
關於超聲波模塊:
超聲波模塊是一種利用超聲波特性來檢測距離的感測器。它有兩個用於發射和接收超聲波的超聲波探頭。測量範圍為 3-450 厘米。需要向Trig 管腳輸入至少10us 的高電平信號,才能觸發超聲波模塊的測距功能。測距功能觸發後,模塊會自動發出8個40kHz的超聲波脈衝,並自動檢測是否有信號返回。此步驟由模塊內部完成。當模塊檢測到回波信號時,ECHO 管腳會輸出高電平。高電平持續時間是超聲波從發出到返回的時間。您可以通過使用時間函數計算高電平持續時間來計算距離。
公式:距離=高電平持續時間*音速(340M/S)/2。
關於紅外避障傳感器:
小車兩側有兩組紅外避障傳感器。
它們的發射管從發光管發射紅外光,接收管接收前方物體反射的紅外光來判斷前方是否有障礙物。
前方有障礙物時,紅外感應腳為低電平,指示燈亮;前方有五個障礙物時,紅外感應針為高電平,指示燈熄滅;因為紅外對管長時間開啟會發熱,縮短使用壽命,所以我們專門為其設計了一個開關,在使用紅外避障前需要開啟。
對於 Raspbot 汽車,我們使用 4 個 TT 直流齒輪馬達。它們由 TB6612 芯片驅動。驅動芯片不直接連接樹莓派引腳。
樹莓派通過IIC與STM8 MUC通信,然後STM8 MCU驅動TB6612芯片馬達。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。根據硬件接口手冊,我們看到超聲波 Echo 和 Trig 引腳連接到樹莓派板的 18 和 16 引腳。
左右紅外避障感測器和開關分別連接樹莓派板的21、19、22腳。
STM8接樹莓派板上的SDA.1、SCL.1。
我們提供了一個專門用於馬達和伺服系統的庫文本——YB_Pcb_Car.py。
它與電機驅動器位於同一目錄中。
樹莓派的管腳對照表如下圖。
關於代碼
代碼路徑: /home/pi/Yahboom_project/Raspbot/2.Hardware Control course/6.Ultrasonic+IR avoid/Ultrasonic+IR avoid.ipynb
1)導入時間、GPIO和YB_Pcb_Car庫2)設置GPIO代碼和超聲波管腳的模式,定義汽車類用於驅動電機或舵機。
設置紅外感應開關管腳為高電平,開啟紅外避障功能。3)定義超聲波測距功能
我們需要給超聲波模塊的TRIG管腳設置一個至少10us的高電平信號來觸發模塊的測距功能。4) 定義超聲波測距優化程序,優化測試結果。5)定義避障功能,完成小車超聲波+IR避障功能。6) 循環調用避障函數,完成避障實驗。當我們點擊停止按鈕時,我們退出循環,停止汽車,並清除汽車類和 GPIO。 運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
程序運行後,我們可以看到小車會向前行駛,遇到前方障礙物時會避開障礙物。
七、追蹤
提示:為了避免陽光影響紅外傳感器,實驗需要在室內進行。
學習目標
在本課程中,我們將學習如何使用跟踪模塊使汽車完成跟踪實驗。
實驗原理
跟踪傳感器的基本原理是利用物體的反射特性。
我們的實驗是跟踪黑線。當紅外光發射到黑線時,會被黑線吸收。當紅外光發射到另一色線時,會反射到紅外接收管。
在檢測不同形狀的軌跡時,4個踪傳感器的狀態如下圖所示。
對於 Raspbot 汽車,我們使用 4 個 TT 直流齒輪馬達。它們由 TB6612 芯片驅動。驅動芯片不直接連接樹莓派引腳。
樹莓派通過IIC與STM8 MUC通信,然後STM8 MCU驅動TB6612芯片馬達。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。根據硬件接口手冊,我們看到跟踪模塊的管腳接在樹莓派板子的11、7、13、15管腳上。STM8接樹莓派板上的SDA.1、SCL.1。我們提供了一個專門用於馬達和伺服系統的庫文本——YB_Pcb_Car.py。它與馬達位於同一目錄中。
樹莓派的管腳對照表如下圖。
關於代碼
路徑:/home/pi/Yahboom_project/Raspbot/2.Hardware Control course/7.Ultrasonic avoid/Tracking test.ipynb
1)導入時間和GPIO庫2)設置GPIO編碼模式,定義跟踪模塊引腳,定義用於驅動電機或舵機的汽車類。3)讀取跟踪模塊的值並打印出來。當我們點擊停止按鈕時,我們退出循環,停止汽車,並清除汽車類和 GPIO。
實驗現象
程序運行後。將汽車放在專用的黑白跟踪圖上,調節跟踪模塊的旋鈕,使感測器檢測到黑色時指示燈亮,檢測到白色時指示燈熄滅。
我們可以看到,當檢測到黑色時,打印 0,當檢測到白色時,打印 1。
路徑: /home/pi/Yahboom_project/Raspbot/2. Hardware Control course / 7.Ultrasonic Avoid/Tracking .ipynb
1)導入時間、GPIO和YB_Pcb_Car庫2)設置GPIO編碼模式,定義跟踪模塊引腳,定義用於驅動電機或舵機的汽車類。3)定義跟踪模塊的功能4) 循環調用跟踪函數完成避障實驗。
當我們點擊停止按鈕時,我們退出循環,停止汽車,並清除汽車類和 GPIO。
實驗現象
在運行跟踪實驗之前。我們需要調整跟踪模塊的靈敏度。檢測到白色時指示燈熄滅,檢測到黑色時指示燈亮。
程序運行後,將小車放在專用的黑白跟踪地圖上,小車就會沿著黑線行駛。
八、限制
提示:為了避免陽光影響紅外傳感器,實驗需要在室內進行。
學習目標
在本課程中,我們將學習如何使用跟踪模塊使汽車完成限制實驗。
實驗原理
跟踪傳感器的基本原理是利用物體的反射特性。 我們的實驗是跟踪黑線。當紅外光發射到黑線時,會被黑線吸收。當紅外光發射到另一色線時,會反射到紅外接收管。
對於 Raspbot 汽車,我們使用 4 個 TT 直流齒輪電機。它們由 TB6612 芯片驅動。驅動芯片不直接連接樹莓派引腳。樹莓派通過IIC與STM8 MUC通信,然後STM8 MCU驅動TB6612芯片驅動馬達。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。根據硬件接口手冊,我們看到跟踪模塊的管腳接在樹莓派板子的11、7、13、15管腳上。
STM8接樹莓派板上的SDA.1、SCL.1。樹莓派的管腳對照表如下圖。
我們提供了一個專門用於驅動馬達和伺服系統的庫文本——YB_Pcb_Car.py。
它與馬達位於同一目錄中。
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2. Hardware Control course /7.Ultrasonic Avoid/Tracking test.ipynb
1)導入時間、GPIO和YB_Pcb_Car庫 2)設置GPIO編碼模式,定義跟踪模塊引腳,定義汽車類用於馬達或舵機。 3) 定義限制 函數4)循環調用限制函數完成避障實驗。 當我們點擊停止按鈕時,我們退出循環,停止汽車,並清除汽車類和 GPIO。
實驗現象
在運行跟踪實驗之前。我們需要調整跟踪模塊的靈敏度。檢測到白色時指示燈熄滅,檢測到黑色時指示燈亮。
程序運行後,將汽車放在白底黑線的範圍內。當汽車遇到黑線時,它會掉頭並始終在黑線範圍內保持移動。
九、LED
學習目標
在本課程中,我們將學習如何在擴展板上使用驅動 LED。
實驗原理
根據硬件接口手冊,LED1 和 LED2 是由樹莓派板子的物理管腳 40 和 38 直接驅動的。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。我們需要控制 Raspberry Pi 板的 40,38 個引腳。
關於代碼
路徑:/home/pi/Yahboom_project/Raspbot/2.Hardware Control course/08.Drive LED/Drive LED.ipynb
1)導入時間和GPIO庫2)設置GPIO編碼模式,設置LED1和LED2為輸出模式3)設置高電平點亮LED4) 設置低電平點亮 LED
運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
當我們運行點亮 LED 燈的程序時,LED1 和 LED2 分別點亮紅色和藍色。
當我們運行關閉 LED 燈的程序時,兩個 LED 燈都是關閉的。
十、IR 紅外線控制測試
為避免陽光對紅外傳感器的干擾,我們必須在室內進行實驗。
遙控時,紅外遙控器需要對準擴展板上的紅外接收器。
學習目標
在本課程中,我們主要學習如何讓汽車上的紅外接收器讀取紅外遙控器的值。
實驗原理
紅外收發碼分為:引導碼、用戶碼、用戶 反碼、操作碼(data code)、 操作反碼(data reverse code)。
下面我們將介紹這幾種編碼波形:
紅外傳輸部分,我們提供的紅外遙控器已經設置好了。所以,我們這裡不講解紅外發射的知識,主要講解紅外接收的一些要點。
我們主要使用 NCE 協議:
協議規定先傳輸低位。
一串信息首先發送一個9ms的AGC(自動增益控制)高脈衝。然後,發送一個 4.5ms 的低電平。接下來,發送四字節地址碼和一個命令碼。這四個字節分別是:地址碼(Address code)、地址反碼(Address reverse code);命令代碼(command code);命令反向代碼(command reverse code)。 1)引導碼: NEC協議的uPD6121G定義的引導碼為9ms高電平+4.5ms低電平,波形如下圖:2)用戶碼和操作碼:NEC協議的uPD6121G定義的用戶碼和操作碼是:
「邏輯0」:0.56ms高電平+0.565ms低電平;
「Logic1」:0.56ms高電平+1.685ms低電平;
波形如下圖:通過紅外接收器後的波輸出,如下圖:如果您一直按該按鈕,則一系列消息只能發送一次。如果您一直按,則以 110 毫秒的周期發送重複代碼。波形如下圖。重複碼由9ms的高AGC電平、2.25ms的低電平、560us的高電平組成,直到按鍵被釋放。波形如下圖:紅外線接收和控制小車的過程如下:
1) 產生一個下降沿,進入外部中斷0的中斷函數,檢查IO口是否經過延時後仍為低電平。如果是低電平,則等待9ms的低電平過去。等待9ms低電平通過,再等待4.5ms高電平通過。
2)開始接收發送的4組數據,等待560us的低電平通過,檢測高電平的持續時間。如果超過1.12ms,則為高電平(高電平持續時間為1.69ms,低電平持續時間為5.65ms。)
3) 檢測接收到的數據是否與數據逆碼(操作逆碼)相同,等待相同的數據。如果相同,則證明接收到紅外遙控器發送的相應數據。然後,小車按照程序中設置的功能移動。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。根據硬件接口手冊,我們知道紅外接收傳感器連接的樹莓派管腳是36。
樹莓派的管腳對照表如下圖所示。
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2. Hardware Control course / 09.IR control test/IR control test.ipynb
1)導入時間和GPIO庫 2)設置GPIO編碼模式,將紅外接收器的GPIO設置為上拉輸入模式3)根據NCE協議,接收紅外信號的導頻碼、地址碼、地址反碼、信號碼、信號反碼。4)根據重複信號判斷按鈕是否鬆開
運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
當我們按下紅外遙控器時,按鈕的編碼值就會被打印出來。
十一、紅外線控制測試
為了避免陽光對紅外傳感器的干擾,我們必須在室內進行實驗。
遙控時,紅外遙控器需要對準擴展板上的紅外接收器。
學習目標
在本課程中,我們主要學習如何使用紅外控制器控制機器人小車。
實驗原理
紅外收發碼分為:引導碼、用戶碼、用戶 反碼、操作碼(data code)、 操作反碼(data reverse code)。
下面我們將介紹這幾種編碼波形:
紅外傳輸部分,我們提供的紅外遙控器已經設置好了。所以,我們這裡不講解紅外發射的知識,主要講解紅外接收的一些要點。
我們主要使用 NCE 協議:協議規定先傳輸低位。
一串信息首先發送一個9ms的AGC(自動增益控制)高脈衝。然後,發送一個 4.5ms 的低電平。接下來,發送四字節地址碼和一個命令碼。這四個字節分別是:地址碼(Address code)、地址反碼(Address reverse code);命令代碼;命令反向代碼。1)引導碼: NEC協議的uPD6121G定義的引導碼為9ms高電平+4.5ms低電平,波形如下圖:2)用戶碼和操作碼:NEC協議的uPD6121G定義的用戶碼和操作碼是:
“邏輯0”:0.56ms高電平+0.565ms低電平;“Logic1”:0.56ms高電平+1.685ms低電平;
波形如下圖:
通過紅外接收器後的波輸出,如下圖:如果您一直按該按鈕,則一系列消息只能發送一次。如果您一直按,則以 110 毫秒的周期發送重複代碼。波形如下圖。重複碼由9ms的高AGC電平、2.25ms的低電平、560us的高電平組成,直到按鍵被釋放。波形如下圖:紅外線接收和控制小車的過程如下:
1) 產生一個下降沿,進入外部中斷0的中斷函數,檢查IO口是否經過延時後仍為低電平。如果是低電平,則等待9ms的低電平過去。等待9ms低電平通過,再等待4.5ms高電平通過。
2)開始接收發送的4組數據,等待560us的低電平通過,檢測高電平的持續時間。如果超過1.12ms,則為高電平(高電平持續時間為1.69ms,低電平持續時間為5.65ms。)
3) 檢測接收到的數據是否與數據逆碼(操作逆碼)相同,等待相同的數據。如果相同,則證明接收到紅外遙控器發送的相應數據。然後,小車按照程序中設置的功能移動。
對於 Raspbot 汽車,我們使用 4 個 TT 直流齒輪馬達。它們由 TB6612 芯片驅動。驅動芯片不直接連接樹莓派引腳。
樹莓派通過IIC與STM8 MUC通信,然後STM8 MCU驅動TB6612芯片驅動馬達。
編碼方式
在本課程中,我們使用 BOARD 編碼方法。根據硬件接口手冊,我們看到 IR 接收器連接到樹莓派板的 36 針。STM8接樹莓派板上的SDA.1、SCL.1。
我們提供了一個專門用於驅動馬達和伺服系統的庫文本——YB_Pcb_Car.py。IR控制器各按鍵對應的碼值如下圖。
關於代碼
路徑: /home/pi/Yahboom_project/Raspbot/2. Hardware Control course / 010.IR control car/IR control car.ipynb
1)導入時間、GPIO和YB_Pcb_Car庫,定義汽車類用於驅動電機或舵機。2)設置GPIO編碼模式,將紅外接收器的GPIO設置為上拉輸入模式。定義口哨功能。3)判斷接收到的紅外遙控按鍵碼值,完成相應動作。4)根據NCE協議,接收紅外遙控器發送的鍵值,判斷釋放。
運行代碼
點擊下圖所示按鈕,在 Jupyter Lab 界面運行程序
實驗現象
程序運行後,將紅外遙控器對準紅外接收器,按不同的按鍵完成相應的動作。
紅外遙控器的對應功能如下圖所示。
AI 相機
一、相機
路徑: /home/pi/Yahboom_project/Raspbot/3.AI Vision course/01.Drive camera/Drive camera . ipynb
OpenCV 使用的常用 API 函數:
1. cv2.VideoCapture()
上限 = cv2.VideoCapture(0)
VideoCapture()中的參數為0,表示樹莓派video0。
(注意:可以通過命令ls/dev/)
cap = cv2.VideoCapture("…/1.avi")
VideoCapture("…/1.avi") ,該參數表示如果輸入影片文件的路徑,則打開影片。
2. cap.set()
相機參數 常用配置方法:
參數 說明:
3 . cap.isOpened()
返回true表示打開相機成功, false表示打開相機失敗
4 . ret,frame = cap.read()
cap.read() 逐幀讀取視頻。ret 和 frame 是 cap.read()函數的兩個返回值。
ret 是一個布爾值,如果讀取的幀正確,則返回 true ,如果文件還沒有讀完,則返回 False。
Frame是每一幀的圖像,是一個三維矩陣。
5 . cv2.waitKey( n )
n 表示延遲時間,如果參數為 1,則表示延遲 1ms 切換到下一幀圖像。
如果參數過大,比如cv2.waitKey(1000),會因為延時過長而死機。
參數為 0 ,如, cv2.waitKey(0) 只顯示當前幀圖像,相當於影片暫停。
6 . cap.release() 和 destroyAllWindows()
調用 cap.release() 釋放影片。
調用destroyAllWindows() 關閉所有圖像窗口。
關於代碼
由於我們整個教程都是在 JupyterLab 中運行的,所以我們必須了解裡面的各種組件。這裡我們需要用到圖像顯示組件。
1.導入庫
import ipywidgets.widgets as widgets
2.設置圖片組件
image_widget = widgets.Image(format='jpeg', width=600, height=500)
3.顯示圖像組件
display(image_widget)
4 .打開相機並讀取圖像
image = cv2.VideoCapture(0) # Open camera
ret, frame = image.read() # Read camera data
5 . 分配給組件
#將圖片轉為jpeg,分配給視頻顯示組件
image_widget.value = bgr8_to_jpeg(frame)
相機畫面如下圖:
二、顏色辨識
HSV色彩空間介紹
HSV(Hue, Saturation, Brightness Value) 是根據顏色的直觀特徵創建的顏色空間,也稱為六角錐模型。
【HSV色彩空間模型】
HSV色彩空間模型(灰色BGR HSV )
在 OpenCV 中,我們經常只使用兩種顏色空間轉換方法,即 BGR-> Gray 和 BGR-> HSV。
!注意:灰色和 HSV 不能相互轉換。
顏色空間轉換函數:cv2.cvtColor(input_image, flag)
BGR-> Gray:標誌為 cv2.COLOR_BGR2GRAY
BGR-> HSV:標誌為 cv2.COLOR_BGR2HSV
OpenCV 中 HSV 顏色空間的取值範圍:
H -- [0, 179] S --[ 0, 255] V -- [0, 255]【常用顏色範圍】
代碼路徑:/home/pi/Yahboom_Project/Raspbot/3.AI Vision course/02.Color recognition
三、HSV 值測試
本課程主要學習根據當前的實驗環境,通過修改默認的HSV值,讓汽車正確識別對應的顏色。
路徑: /home/pi/Yahboom_project/Raspbot/3.AI Vision course/02.Color recognition/Color recognition+button.ipynb
1.運行程序 到如下圖所示的地方。然後,我們可以調整滑塊來改變HSV 值,以確保當前顏色可以被正確識別(例如,紅色)。如下圖,可以準確識別紅色。將程序運行到 如下圖所示的地方結束這個過程。 2.運行程序 到如下圖所示的地方。選擇顏色按鈕。然後,您將看到綠色對象將被識別。如下所示。路徑:
/home/pi/Yahboom_project/Raspbot/3.AI Vision course/02.Color recognition/Color detection.ipynb
這是程序可以同時識別多個顏色對象。
四、相機顏色追蹤
路徑: /home/pi/Yahboom_project/Raspbot/3.AI Vision course/03.Color tracking
運行程序後,當相機檢測到目標色物體時,相機會隨物體移動。
五、小車顏色追蹤
路徑: /home/pi/Yahboom_project/Raspbot/3.AI Vision course/04.Color follow /Color_follow.ipynb
運行程序後,當相機檢測到相應的色塊時,小車就會隨著物體移動。
六、TensorFlow 物體辨識
TensorFlow 是一個開源軟件庫,它使用數據流圖進行數值計算。
特色 - 高靈活性
- 真正的便攜性
- 連接科研和產品
- 自動區分
- 支持 多國語言
- 性能優化
代碼路徑:/home/pi/Yahboom_Project/Raspbot/3.AI Vision course/05.Object recognition/Object recognition.ipynb
這個程序在JupyterLab上運行,幀率很低,但是你可以在R aspberry Pi桌面 上試試python程序,效果會更好。
七、QR code 辨識
QR code簡介
QR code是利用一定的幾何圖形,按照一定的規則以黑白圖案分佈在平面(二維方向)上的數據符號信息記錄下來的。
代碼路徑:/home/pi/Yahboom_Project/Raspbot/3.AI Vision course/06.QR code recognition/QR code recognition.ipynb
運行上述程序後,在鏡頭前放一個QR Code,即可識別。我們可以點擊暫停按鈕來停止這個過程。如下所示。
八、QR code 操控
如下圖所示,五個 QR Code 對應不同的功能,可以用來控制機器人的運動。
前 後
左右 停
/home/pi/Yahboom_Project/Raspbot/3.AI Vision course/07.QR code control/QR code control.ipynb
九、人臉偵測
在OpenCV中,影片中的人臉偵測只從相機讀取每一幀圖像,然後使用靜態圖像檢測方法進行檢測。人臉檢測需要分類器:
@人臉檢測器(預設):haarcascade_frontalface_default.xml
@人臉檢測器(快速哈爾):haarcascade_frontalface_alt2.xml
@人臉檢測器(側視圖):haarcascade_profileface.xml
@眼睛檢測器(左眼):haarcascade_lefteye_2splits.xml
@眼睛檢測器(右眼):haarcascade_righteye_2splits.xml
@嘴巴探測器:haarcascade_mcs_mouth.xml
@鼻子檢測器:haarcascade_mcs_nose.xml
@身體檢測器:haarcascade_fullbody.xml
@人臉檢測器(快速LBP ):lbpcascade_frontalface.xml
@ 只能檢測到睜眼:haarcascade_eye.xml
@ 只能檢測到戴眼鏡的人:haarcascade_eye_tree_eyeglasses.xml
@https://github.com/opencv/opencv/tree/master/data 下載分類器文件連結
haarcascade_profileface.xml 是 Haar 的級聯數據。這個xml可以從這個連結https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_profileface.xml
接下來,我們可以 通過face_cascade.detectMultiScale()開始人臉偵測。我們需要將圖像轉換成灰度圖,然後將相機得到的每一幀圖像轉入 .detectMultiScale()中。
(注意:我們需要確保正確輸入haarcascade_profileface.xml的正確位置。)
OpenCV API 函數:
detectMultiScale ( const Mat& image, vector& objects, double scaleFactor=1.1 , int minNeighbors, int flag , cvSize )
參數分析:
image --- 輸入灰度圖像
objects --- 檢測到的物體的矩形框向量集
scaleFactor --- 圖像比例中的每個比例參數,默認值為1.1。
minNeighbors --- 默認為 3。
minNeighbors --- 默認值 3 表示至少有 3 次重疊檢測,所以我們認為人臉是存在的。
minSize --- 目標最小尺寸
maxSize --- 目標最大尺寸
代碼路徑:
/home/pi/Yahboom_Project/ Raspbot/ 3.AI Vision course/08.Face detection /Face detection.ipynb
因為我們選擇的是側臉的模型,運行上面的程序後,我們就可以識別出側臉了。
十、人臉追蹤
/home/pi/Yahboom_Project/ Raspbot/ 3.AI Vision course/09.Face tracking /Face tracking.ipynb
十一、手勢辨識
手勢識別
樹莓派的計算能力有限,所以我們直接使用百度API,每天免費使用5萬次。只為學習。請勿將其用於商業目的。您需要購買相關服務。我公司概不負責。
支援23種手勢識別。
除了手勢辨識。如果在圖像中偵測到人臉,它會同時返回到人臉框的位置。
首先,我們需要遠程連接樹莓派並啟用相機。
然後,我們需要通過 sudo pip3 install baidu-aip 命令安裝百度的 API 庫
接口函數:
手勢辨識返回數據參數詳細訊息。手勢辨識返回一個例子。
代碼路徑:
/home/pi/Yahboom_Project/Raspbot/3.AI Visual course/10.Gesture recognition
運行上述程序後,樹莓派界面會打印出如下圖所示的數據。 十二、自動駕駛
路徑:/home/pi/Yahboom_Project/ Raspbot/ 3.AI Vision course/12.Autopilot /Autopilot.ipynb
OpenCV 坐標系
row == heigh == Point.y
col == width == Point.x
Mat::at(Point(x, y)) == Mat::at(y,x) 獲取圖片:ret, frame = image.read()
圖像調整大小:frame = cv2.resize(frame,(320,240))
透視變換
因為相機看到的畫面是扭曲的,所以我們需要通過透視變換將身體前方的區域變成俯視圖。然後放大整個圖片區域。
如下圖,左邊是原始相機圖片,右邊是透視變換後的圖片。 【原相機圖片】 【透視變換後的圖片】
功能:
matSrc = np.float32([[0, 149], [310, 149], [271, 72], [43, 72]])
matDst = np.float32([[0,240], [310,240], [310,0], [0,0]])
matAffine = cv2.getPerspectiveTransform (matSrc, matDst) # mat 1 src 2 dst
dst = cv2.warpPerspective(frame,matAffine,(320,240))
然後,我們可以根據透視坐標繪製矩形。
# D raw rectangle box
pts = np.array([[0, 149], [310, 149], [271, 72], [43, 72]], np.int32)
pts = pts.reshape((-1, 1, 2))
cv2.polylines(frame, [pts],True, (255, 0, 0), 3)
二值圖像
二值化的核心思想是設置一個閾值,大於閾值的值為0(黑色)或255(白色),使得圖像稱為黑白。閾值可以是固定的或自適應的。
Python-OpenCV 中提供了閾值函數:
cv2.threshold (src, threshold, maxValue, method )
例如:
dst_gray = cv2.cvtColor(dst, cv2.COLOR_RGB2GRAY)
dst_retval, dst_binaryzation = cv2.threshold(dst_gray, 110, 255, cv2.THRESH_BINARY)
對圖片進行透視變換後,轉換後的圖像如下圖所示。
取得黑線的邊緣,畫線
畫線的目的是為了方便用戶檢查上述過程是否有問題。畫出黑線兩條邊的位置,以及圖像中心線和黑線中心的位置。 - 透視後的圖片尺寸還是320*240,所以圖片的中心線為:midpoint: 320/2-1=159或者:midpoint = np.int(histogram.shape[0]/2)
- 在黑線左側搜索:取左圖的最小索引,實現如下函數:leftx_base = np.argmax(histogram[:midpoint],axis = 0)
- 搜索找到黑線的右線:反轉圖像,取圖像左側最小值的索引,然後從圖像寬度中減去該索引:
- rightx_base = np.argmin(histogram[::-1][:rightpoint], axis = 0) #反轉直方圖,取最右邊的值
- rightx_base = 319-rightx_base
- 實際中線位置計算:(左線+右線)/2
- lane_center = int((leftx_base + rightx_base)/2) #左右線的中間位置
- Image centerline : cv2.line(dst_binaryzation, (159,0), (159,240),(255,0,255),2) #紫色
- 左行:cv2.line(dst_binaryzation,(leftx_base,0),(leftx_base,240),(0,255,0),2) #green
- 右行:cv2.line(dst_binaryzation,(rightx_base,0),(rightx_base,240),(0,255,0),2) # green
- 實際中線:cv2.line(dst_binaryzation,(lane_center,0),(lane_center,240),(255,0,0),2)#藍色
計算偏移量
在步驟5中找到Autopilot的白線後 ,我們可以根據實際中心線與圖像中心線之間的差異來知道車身偏差的大小,從而可以控制汽車來糾正偏差以實現自動駕駛儀的目的。
計算方法:
Bias = midpoint-lane_center
根據偏移值的符號和大小,我們將其限制在-20~20,即轉向的最大速度為20,以防止轉向過快失去賽道的白線。
轉向角PID調節:
Z_axis_pid.SystemOutput = Bias
Z_axis_pid.SetStepSignal(0)
Z_axis_pid.SetInertiaTime(0.5, 0.2)
在 PID 計算之後,PID 輸出也被限制在最大值±20。
if Z_axis_pid.SystemOutput > 20:
Z_axis_pid.SystemOutput = 20
elif Z_axis_pid.SystemOutput < -20:
Z_axis_pid.SystemOutput = -20
控制機器人完成一次自動駕駛
圖1 圖2 圖3 圖4
圖一:輕微偏離,直走。
圖2:右轉糾正較大的右偏。
圖3:左右角度造成的偏差通過原位轉動進行校準。
圖4:通過直角時圖片丟失,根據檢測前的狀態判斷旋轉方向。
關於代碼:
電池與充電
- 請使用我們提供的充電器為電池組充電。
- 充電時不能使用汽車和電池組。
- 電壓在9V左右需要及時充電。充電完成後,電池電壓約為12.6V。
- 如果長時間不使用汽車,應從汽車底板上拔下電瓶線。因為即使汽車處於待機狀態,電池也會耗盡。
- 如果您長時間沒有使用汽車,下次使用前需要將電池充滿電,然後再使用汽車。
- 電池充電時,充電器指示燈亮紅色,充電完成後指示燈變為綠色。 充電完成後,應及時拔掉充電器和電源插頭,以免過度充電而損壞電池。