코드 15-2 kNN 알고리즘을 이용한 필기체 숫자 학습 [ch15/knndigits]
01 Ptr<KNearest> train_knn() 02 { 03 Mat digits = imread("digits.png", IMREAD_GRAYSCALE); 04 05 if (digits.empty()) { 06 cerr << "Image load failed!" << endl; 07 return 0; 08 } 09 10 Mat train_images, train_labels; 11 12 for (int j = 0; j < 50; j++) { 13 for (int i = 0; i < 100; i++) { 14 Mat roi, roi_float, roi_flatten; 15 roi = digits(Rect(i * 20, j * 20, 20, 20)); 16 roi.convertTo(roi_float, CV_32F); 17 roi_flatten = roi_float.reshape(1, 1); 18 19 train_images.push_back(roi_flatten); 20 train_labels.push_back(j / 5); 21 } 22 } 23 24 Ptr<KNearest> knn = KNearest::create(); 25 knn->train(train_images, ROW_SAMPLE, train_labels); 26 27 return knn; 28 }
• 3행 digits.png 영상을 불러와 digits에 저장합니다.
• 12~13행 digits.png 영상에 가로 100개, 세로 50개의 필기체 숫자가 적혀 있으므로 for 반복문 범위를 동일하게 설정합니다.
• 15행 가로 i번째, 세로 j번째 필기체 숫자 영상을 roi에 저장합니다.
• 16행 roi 영상 자료형을 float로 변환하여 roi_float에 저장합니다.
• 17행 20×20 roi_float 영상을 400×1 크기의 영상으로 변환하여 roi_flatten에 저장합니다.
• 19행 roi_flatten 영상을 train_images 행렬의 맨 아래 행으로 추가합니다.
• 20행 train_labels 행렬의 맨 아래에 현재 추가한 필기체 숫자 영상의 정답(레이블)을 추가합니다.
• 24~25행 KNearest 객체 knn을 생성하고, kNN 학습을 수행합니다. knn->train() 함수 인자로 사용되는 train_images 행렬 크기는 5000×400이고, train_labels 행렬 크기는 5000×1입니다.
• 27행 학습된 knn 스마트 포인터를 반환합니다.