printf("ho_tari\n");

Chapter 15 : 머신 러닝 본문

OpenCV

Chapter 15 : 머신 러닝

호타리 2023. 9. 18. 17:20

<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 결과>

마우스를 이용하여 1을 입력 후 스페이스바를 누르면 결과창에 1이라고 출력됨
마우스를 이용하여 2 입력 후 스페이스바를 누르면 결과창에 2라고 출력됨
마우스를 이용하여 3을 입력 후 스페이스바를 누르면 결과창에 3이라고 출력됨
마우스를 이용하여 4를 입력 후 스페이스바를 누르면 결과창에 4라고 출력됨
마우스를 이용하여 5를 입력 후 스페이스바를 누르면 결과창에 5라고 출력됨
마우스를 이용하여 6을 입력 후 스페이스바를 누르면 결과창에 6라고 출력됨

'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