Recent Posts
printf("ho_tari\n");
Chapter 15 : 머신 러닝 본문
<OpenCV_Projects.cpp>
#include <opencv2/opencv.hpp>
extern void do_knn_machine_learning();
int main()
{
do_knn_machine_learning();
}
<do_knn_machine_learning.cpp>
#pragma once
#include <opencv2/opencv.hpp>
// 스마트 포인터
static cv::Ptr<cv::ml::KNearest> train_knn()
{
cv::Mat digits = cv::imread("digits.png", cv::IMREAD_GRAYSCALE);
if (digits.empty()) return nullptr;
cv::Mat train_images;
cv::Mat train_labels;
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 100; ++j)
{
cv::Mat roi = digits(cv::Rect(j * 20, i * 20, 20, 20));
cv::Mat roi_float;
roi.convertTo(roi_float, CV_32FC1); //openCV 자료형
cv::Mat roi_flatten = roi_float.reshape(1, 1); // 1차원 벡터 20 * 20 = 400
train_images.push_back(roi_flatten);
train_labels.push_back(i / 5);
}
}
cv::Ptr<cv::ml::KNearest> knn = cv::ml::KNearest::create(); // Singular
knn->train(train_images, cv::ml::ROW_SAMPLE, train_labels);
return knn;
}
static cv::Point point_prev(-1, -1); // 마우스를 떼면 가운데로 오게 함
static void on_mouse(int event, int x, int y, int flag, void* userdata)
{
cv::Mat src = *(static_cast<cv::Mat*>(userdata));
if (event == cv::EVENT_LBUTTONDOWN)
{
point_prev = cv::Point(x, y);
}
else if (event == cv::EVENT_LBUTTONUP)
{
point_prev = cv::Point(x, y);
}
else if (event == cv::EVENT_MOUSEMOVE && (flag &cv::EVENT_FLAG_LBUTTON))
{
cv::line(src, point_prev, cv::Point(x, y), cv::Scalar(255, 255, 255), 30, cv::LINE_AA, 0);
point_prev = cv::Point(x, y);
cv::imshow("DISPLAY", src);
}
}
void do_knn_machine_learning()
{
cv::Ptr<cv::ml::KNearest> knn = train_knn();
if (knn.empty())
{
std::cerr << "Training 실패" << std::endl;
return;
}
std::cout << "학습을 성공적으로 하였습니다." << std::endl;
cv::Mat input_display = cv::Mat::zeros(400, 400, CV_8UC1);
cv::namedWindow("DISPLAY", cv::WINDOW_NORMAL);
cv::setMouseCallback("DISPLAY", on_mouse, (void*)&input_display);
while (true)
{
int keyboard_key = cv::waitKey();
if (keyboard_key == 27) break;
else if (keyboard_key == ' ') // spacebar 입력
{
cv::Mat image_resize;
cv::Mat image_float; // CV_32FC1으로 변환을 위한 행렬
cv::Mat image_flatten; // 1 X 400
cv::Mat resource;
cv::resize(input_display, image_resize, cv::Size(20, 20), 0, 0, cv::INTER_AREA);
image_resize.convertTo(image_float, CV_32FC1);
image_flatten = image_float.reshape(1, 1); // 1행으로 -> 1 X 400
knn->findNearest(image_flatten, 5, resource); // k = 5 (선택가능 : 3, 5, 7, 9)
std::cout << cvRound(resource.at<float>(0, 0)) << std::endl;
input_display.setTo(0); // 입력창 화면을 검게하기 위해서
cv::imshow("DISPLAY", input_display);
}
}
cv::destroyAllWindows();
}
<compile 결과>
'OpenCV' 카테고리의 다른 글
Examples (0) | 2023.09.18 |
---|---|
Chapter 11 : 이진화와 모폴로지 (0) | 2023.09.18 |
Chapter 10 : 컬러 영상 처리 (0) | 2023.09.18 |
Chapter 9 : 에지 검출과 응용 (0) | 2023.09.18 |
Chapter 8 : 영상의 기하학적 변환 (0) | 2023.09.18 |