點擊上方「AI算法與圖像處理」,選擇加"星標"或「置頂」javascript
重磅乾貨,第一時間送達java
本期咱們將一塊兒學習如何使用計算機視覺技術識別棋子及其在棋盤上的位置
python
咱們利用計算機視覺技術和卷積神經網絡(CNN)爲這個項目建立分類算法,並肯定棋子在棋盤上的位置。最終的應用程序會保存整個圖像並可視化的表現出來,同時輸出棋盤的2D圖像以查看結果。git
(左)實時攝像機進給的幀和棋盤的(右)二維圖像github
咱們對該項目的數據集有很高的要求,由於它最終會影響咱們的實驗結果。咱們在網上能找到的國際象棋數據集是使用不一樣的國際象棋集、不一樣的攝影機拍攝獲得的,這致使咱們建立了本身的數據集。我使用國際象棋和攝像機(GoPro Hero6 Black以「第一人稱視角」角度)生成了自定義數據集,這使個人模型更加精確。該數據集包含2406張圖像,分爲13類(請參閱下文)。總結:這花費了咱們不少時間,可是這使得訓練圖像儘量地接近在應用程序中使用時所看到的圖像。算法
自定義數據集的細分微信
爲了構建該數據集,我首先建立了capture_data.py,當單擊S鍵時,該視頻從視頻流中獲取一幀並將其保存。這個程序使我可以無縫地更改棋盤上的棋子並一遍又一遍地捕獲棋盤的圖像,直到我創建了大量不一樣的棋盤配置爲止。接下來,我建立了create_data.py,以使用下一部分中討論的檢測技術將其裁剪爲單獨小塊。最後,我經過將裁剪後的圖像分紅帶標籤的文件夾來對它們進行分類。網絡
對於棋盤檢測,我想作的事情比使用OpenCV函數findChessboardCorners複雜的多,但又不像CNN那樣高級。使用低級和中級計算機視覺技術來查找棋盤的特徵,而後將這些特徵轉換爲外邊界和64個獨立正方形的座標。該過程以Canny邊緣檢測和Hough變換生成的相交水平線、垂直線的交點爲中心。層次聚類用於按距離對交叉點進行分組,並對各組取平均值以建立最終座標(請參見下文)。app
完整的棋盤檢測過程編輯器
項目伊始,咱們想使用Keras / TensorFlow建立CNN模型並對棋子進行分類。可是,在建立數據集以後,僅考慮CNN的大小,單靠CNN就沒法得到想要的結果。爲了克服這一障礙,我利用了ImageDataGenerator和transfer learning,它增長了個人數據並使用了其餘預訓練的模型做爲基礎。
建立CNN模型
爲了使用GPU,我在雲中建立並訓練了CNN模型,從而大大減小了訓練時間。快速提示:Google Colab是使用GPU快速入門的簡便方法。爲了提升數據的有效性,我使用了ImageDataGenerator來擴展原始圖像並將模型暴露給不一樣版本的數據。ImageDataGenerator函數針對每一個時期隨機旋轉,從新縮放和翻轉(水平)訓練數據,從本質上建立了更多數據。儘管還有更多的轉換選項,但這些轉換選項對該項目最有效。
from keras.preprocessing.image import ImageDataGeneratordatagen = ImageDataGenerator( rotation_range=5, rescale=1./255, horizontal_flip=True, fill_mode='nearest')test_datagen = ImageDataGenerator(rescale=1./255)train_gen = datagen.flow_from_directory( folder + '/train', target_size = image_size, batch_size = batch_size, class_mode = 'categorical', color_mode = 'rgb', shuffle=True)test_gen = test_datagen.flow_from_directory( folder + '/test', target_size = image_size, batch_size = batch_size, class_mode = 'categorical', color_mode = 'rgb', shuffle=False)
咱們沒有從頭開始訓練模型,而是經過利用預先訓練的模型並添加了使用個人自定義數據集訓練的頂層模型來實現轉移學習。我遵循了典型的轉移學習工做流程:
1.從先前訓練的模型(VGG16)中獲取圖層。
from keras.applications.vgg16 import VGG16model = VGG16(weights='imagenet')model.summary()
2.凍結他們,以免破壞他們在訓練回合中包含的任何信息。
3.在凍結層的頂部添加了新的可訓練層。
from keras.models import Sequentialfrom keras.layers import Dense, Conv2D, MaxPooling2D, Flattenfrom keras.models import Modelbase_model = VGG16(weights='imagenet', include_top=False, input_shape=(224,224,3)) # Freeze convolutional layers from VGG16for layer in base_model.layers: layer.trainable = False# Establish new fully connected blockx = base_model.outputx = Flatten()(x) x = Dense(500, activation='relu')(x) x = Dense(500, activation='relu')(x)predictions = Dense(13, activation='softmax')(x)# This is the model we will trainmodel = Model(inputs=base_model.input, outputs=predictions)model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy'])
4.在自定義數據集上訓練新層。
epochs = 10history = model.fit( epochs=epochs, verbose = 1, validation_data=test_gen)model.save_weights('model_VGG16.h5')
當咱們使用VGG16或VGG19做爲預訓練模型建立模型時,因爲驗證精度更高,所以選擇了使用VGG16的模型。另外,最佳epochs 是10。任何大於10的數均不會使驗證準確性的提升,也不會增長訓練與驗證準確性之間的差別。總結:轉移學習使咱們能夠充分利用深度學習在圖像分類中的優點,而無需大型數據集。
爲了更好地可視化驗證準確性,我建立了模型預測的混淆矩陣。經過此圖表,能夠輕鬆評估模型的優缺點。優勢:空-準確率爲99%,召回率爲100%;白棋和黑棋(WP和BP)-F1得分約爲95%。劣勢:白騎士(WN)-召回率高(98%),但準確性卻很低(65%);白主教(WB)-召回率最低,爲74%。
測試數據的混淆矩陣
該應用程序的目標是使用CNN模型並可視化每一個步驟的性能。咱們建立了cv_chess.py,它清楚地顯示了步驟,並創建了cv_chess_functions.py,它顯示了每一個步驟的詳細信息。此應用程序保存實時視頻流中的原始幀,每一個正方形的64個裁剪圖像以及棋盤的最終2D圖像。
print('Working...') # Save the frame to be analyzed cv2.imwrite('frame.jpeg', frame) # Low-level CV techniques (grayscale & blur) img, gray_blur = read_img('frame.jpeg') # Canny algorithm edges = canny_edge(gray_blur) # Hough Transform lines = hough_line(edges) # Separate the lines into vertical and horizontal lines h_lines, v_lines = h_v_lines(lines) # Find and cluster the intersecting intersection_points = line_intersections(h_lines, v_lines) points = cluster_points(intersection_points) # Final coordinates of the board points = augment_points(points) # Crop the squares of the board a organize into a sorted list x_list = write_crop_images(img, points, 0) img_filename_list = grab_cell_files() img_filename_list.sort(key=natural_keys) # Classify each square and output the board in Forsyth-Edwards Notation (FEN) fen = classify_cells(model, img_filename_list) # Create and save the board image from the FEN board = fen_to_image(fen) # Display the board in ASCII print(board)# Display and save the chessboard image board_image = cv2.imread('current_board.png') cv2.imshow('current board', board_image) print('Completed!')
代碼連接:https://github.com/andrewleeunderwood/project_MYM
下載1:何愷明頂會分享
在「AI算法與圖像處理」公衆號後臺回覆:何愷明,便可下載。總共有6份PDF,涉及 ResNet、Mask RCNN等經典工做的總結分析
下載2:leetcode 開源書
在「AI算法與圖像處理」公衆號後臺回覆:leetcode,便可下載。每題都 runtime beats 100% 的開源好書,你值得擁有!
下載3 CVPR2020
在「AI算法與圖像處理」公衆號後臺回覆: CVPR2020 ,便可下載1467篇CVPR 2020論文 我的微信(若是沒有備註不拉羣!) 請註明: 地區+學校/企業+研究方向+暱稱
以爲不錯就點亮在看吧
![]()
本文分享自微信公衆號 - AI算法與圖像處理(AI_study)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。