더북(TheBook)

코드 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 스마트 포인터를 반환합니다.