Python OpenCV 实现魔方识别+复原
簡介
本項目運用了基礎的 Opencv 圖像處理算法 來實現魔方色塊的識別并判斷顏色。 用戶可以通過將魔方舉在攝像機的前方來讓機器自動將魔方的色塊錄入數據,然后系統將會依靠用戶錄入的數據來產生當前魔方的解法,并以動畫的形式展現出來。
圖形用戶界面展示:
如何使用
使用到的庫:
在 Anaconda 環境下安裝庫:
conda install -c anaconda tk conda install -c conda-forge numpy conda install -c conda-forge opencv配置完環境后:
在已具備所有需要的庫之后,到 Rubik-s-Cube-Scanner-Solver 將該repo下的 RubiksCubeScanner 路徑克隆到電腦中,然后使用python3 運行 client_gui.py 即可。
當該代碼第一次運行時,系統需要創建解魔方需要使用到的表格,一般需要花半個小時到一個小時,請耐心等待,并且會占用額外的80MB左右的硬盤空間。此后執行則不需要創建列表,圖形化用戶界面會直接顯示。
當用戶界面顯示,用戶可以直接用客戶端里的色盤來給魔方上色,也可以點擊 “Turn on cam" 來打開攝像頭,讓攝像頭來自動識別+讀入當前魔方的內容。
在整個魔方已經被填充后,點擊 ”Solve“ 系統將會連接到之前已經創建的列表并開始解輸入的魔方。輸出的解法的步驟數會在20步以內。
在魔方已經被解完后,點擊 ”Animate“ 即可讓魔方“動起來”,作者提前制作的魔方動畫將會開始播放解法。左下角可拖動的塊可以用來調節動畫播放的速度。
實現步驟
本項目可以大致地分為三個步驟 :
1. 檢測并錄入魔方的內容
2. 生成已錄入魔方的解法
3. 創建可以展示給用戶的魔方動畫
接下來的文章將會對每一個步驟,尤其是第一個步驟進行詳細的分解。
1. 檢測并錄入魔方的內容
識別魔方色塊
為了減少不必要的運算,在窗體程序的攝像機讀取的視屏中間畫有一個正方形,所有算法在該正方形中運行。使用 ROI(Region of Interest) 提升運算效率是非常實用的算法優化。
一張普通的彩色圖片在每個像素含有一個 (0-255,0-255,0-255) 的數組, 也就是說在一個像素可以有 256x256x256 = 1703936 種不同的顏色變換。然而一張二值化后的圖在每個像素僅僅包含 0 或者 1 兩種可能。一張彩色圖片所包含的信息遠遠大于它的二值化后的圖片,二值圖所包含的主要信息僅僅是圖片中物體的輪廓。我們識別魔方色塊只需要物體的輪廓信息,所以我們的第一個步驟是將讀取到的圖像二值化。
在Python OpenCV 中, 二值化圖片的代碼為:
// 首先將彩色圖片處理成灰度圖 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)// img(gray): 待處理的圖片 // threshold1(130): 將低于該值的像素歸為 0 // threshold2(230): 將高于該值的像素歸為 0 // option: 二值化選項 // thresh1: 返回的二值化后的圖片 ret,thresh1 = cv2.threshold(gray,130,230,cv2.THRESH_BINARY)在圖片已經被二值化后,我們還需要進行一些圖像處理讓我們獲得的數據更加可靠:
// kenel 是一個算子,它可以是我們自定義的形狀,Opencv 將以它的形狀進行填充以及腐蝕 // dilate 是opencv的膨脹算法,將它運用在有時模糊的數據中可以讓該數據更加穩定 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2,2)) binary_dilated = cv2.dilate(binary_Image,kernel,iterations = 5)下面的圖片: 左邊為膨脹前,右邊為膨脹后
將我們的圖片膨脹完后,即可開始提取輪廓線,在opencv中算法:
接下來可以在contours 矩陣中尋找為四邊形的輪廓線,為此opencv提供了算法:
for cnt in contours: approx = cv2.approxPolyDP(cnt,0.12*cv2.arcLength(cnt,True),True)x = approx.ravel()[0]y = approx.ravel()[1]if (len(approx) == 4 and 245<x<395 and 105<y<255):這個循環會把contours中的每一個輪廓線都過一遍,如果該輪廓線不能被估作一個四邊形,則舍棄;如果可以,則進入下一步繼續判斷該四邊形是否為正方形:
if approx_is_square(approx) == Trueapprox_is_square(approx) 是作者自己寫的函數,它非常簡單。通過比對這個四邊形四個邊的長度是否在其中任意一邊的90%~110%之間,再通過比對這四個邊之間的角度是否都在80度到100度;這個算法可以粗略地判斷輸入的形狀是否是正方形。
在識別完正方形后,我們即可數當前圖片ROI 中的正方形的數量,如果等于9,就將他們標識出來,最基礎的色塊識別已經完成!
識別某個色塊的顏色
對于我們而言,一個色塊可以是“綠“,”紅”,“藍”,“白“ 等等。 然而對于一個機器而言一個色塊的顏色僅僅是一個RGB值。我們為了知道一個色塊歸屬于魔方的哪一面則需要知道當前色塊的區域的rgb值代表什么顏色。
第一步是遍歷該色塊,把所有屬于本色塊的像素的顏色全部加起來,然后除以加起來的像素的數量,這樣獲得一個當前色塊的平均顏色。
接下來我們可以提前設立很多閥值來判斷一個色塊的平均顏色到底屬于什么顏色:
red_low = [30,30,100] #bgr 格式下紅色的最低值 red_high = [150,150,255] #bgr 格式下紅色的最高值如果: red_low < 平均顏色 < red_high 則: 該顏色是紅色好了,這樣我們就完成了顏色的判斷!我們已經可以把顏色填入GUI中的矩陣中了!
總結
以上是生活随笔為你收集整理的Python OpenCV 实现魔方识别+复原的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器人三大定律的发展和演进概述
- 下一篇: python-pcl函数_Python简