Opencv kmean,knn,svm,demo

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;

void get_hog_descriptor(Mat& image, vector<float>& desc) {
	HOGDescriptor hog;
	int h = image.rows;
	int w = image.cols;
	float rate = 64.0 / w;
	Mat img, gray;
	resize(image, img, Size(64, int(rate * h)));
	cvtColor(img, gray, COLOR_BGR2GRAY);
	Mat result = Mat::zeros(Size(64, 128), CV_8UC1);
	result = Scalar(127);
	Rect roi;
	roi.x = 0;
	roi.width = 64;
	roi.y = (128 - gray.rows) / 2;
	roi.height = gray.rows;
	gray.copyTo(result(roi));
	hog.compute(result, desc, Size(8, 8), Size(0, 0));
	// printf("desc len : %d \n", desc.size());
}
void svm_train(Mat& trainData, Mat& labels) {
	using namespace cv::ml;
	printf("\n start SVM training... \n");
	Ptr<ml::SVM> svm =ml:: SVM::create();
	svm->setC(2.67);//对离群点的容忍度,C越大,边界可能越小
	svm->setType(SVM::C_SVC);
	svm->setKernel(SVM::LINEAR);
	svm->setGamma(5.383);//高斯核的大小,只对svm->setKernel() SVM::POLY,SVM::RBF,SVM::SIGMOID有效
	svm->train(trainData, ROW_SAMPLE, labels);
	clog << "....[Done]" << endl;
	printf("end train...\n");

	// save xml
	svm->save("D:/images/train_data/elec_watch/hog_elec.xml");
}
int main(int argc, char** argv)
{
	Mat img = imread("xxx.jpg");


	//kmean
	int dims = img.channels();
	Mat sample_data = img.reshape(dims, img.cols * img.rows);//变形的通道数,行数
	sample_data.convertTo(sample_data, CV_32F);

	Mat labels, centerpoints;
	int clustercount = 5;//分类数量
	TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
	kmeans(sample_data, clustercount, labels, criteria, clustercount, KMEANS_PP_CENTERS, centerpoints);

	//显示结果
	int index = 0;
	Mat result = Mat::zeros(img.size(), img.type());
	for (int row = 0; row < img.rows; row++)
	{
		for (int col = 0; col < img.cols; col++)
		{
			index = labels.at<int>(row * img.cols + col, 0);
			result.at<Vec3b>(row, col) = Vec3b(index*40, 1, 1);
		}
	}
	//KNN 图像分类,opencv有一个digits.png,有0-9手写数字共5000个,图像大小1000*2000,每个样本20*20
	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	//准备数据集
	Mat datas = Mat::zeros(5000, 20 * 20, CV_8SC1);
	Mat labels = Mat::zeros(5000, 1, CV_8UC1);

	int index = 0;
	Rect roi;
	roi.x = 0;
	roi.height = 1;
	roi.width = 400;

	for (int row = 0; row < 50; row++)
	{
		int label = row / 5;
		int offsety = row * 20;
		Mat digital = Mat::zeros(20, 20, CV_8SC1);
		for (int col = 0; col < 100; col++)
		{
			int offsetx = col * 20;
			digital = (gray.clone())(Rect(offsetx,offsety,20,20));
			Mat one_row = digital.reshape(1, 1);
			roi.y = index;
			one_row.copyTo(datas(roi));
			index++;
			labels.at<int>(index, 0) = label;

		}
		
	}
	datas.convertTo(datas, CV_32F);
	labels.convertTo(labels, CV_32F);
	//开始训练
	Ptr<ml::KNearest>knn = ml::KNearest::create();
	knn->setDefaultK(5);
	knn->setIsClassifier(true);
	Ptr<ml::TrainData>traindata = ml::TrainData::create(datas, ml::ROW_SAMPLE, labels);
	knn->train(traindata);
	knn->save("D://num.yml");


	//加载KNN
	Ptr<ml::KNearest>knn_test = Algorithm::load<ml::KNearest>("D://num.yml");
	Mat test;
	Mat result;
	resize(test, test, Size(20, 20));
	test.reshape(1, 1);
	knn_test->findNearest(test, 5, result);
	cout << "pridect:" << result.at<float>(0, 0);

	//SVM
	Mat trainData = Mat::zeros(Size(3780, 26), CV_32FC1);
	Mat labels = Mat::zeros(Size(1, 26), CV_32SC1);
	vector<string> images;
	string positive_dir;//路径
	glob(positive_dir, images);
	int pos_num = images.size();
	for (int i = 0; i < images.size(); i++) {
		Mat image = imread(images[i].c_str());
		vector<float> fv;
		get_hog_descriptor(image, fv);
		for (int j = 0; j < fv.size(); j++) {
			trainData.at<float>(i, j) = fv[j];
		}
		labels.at<int>(i, 0) = 1;
	}
	images.clear();
	string negative_dir;//路径
	glob(negative_dir, images);
	for (int i = 0; i < images.size(); i++) {
		Mat image = imread(images[i].c_str());
		vector<float> fv;
		get_hog_descriptor(image, fv);
		for (int j = 0; j < fv.size(); j++) {
			trainData.at<float>(i + pos_num, j) = fv[j];
		}
		labels.at<int>(i + pos_num, 0) = -1;
	}
	// SVM train, and save model
	svm_train(trainData, labels);

	//加载模型
	Ptr<ml::SVM> svm = ml::SVM::load("D:/images/train_data/elec_watch/hog_elec.xml");

	//  detect custom object
	Mat test = imread("D:/images/train_data/elec_watch/test/scene_02.jpg");
	resize(test, test, Size(0, 0), 0.2, 0.2);
	imshow("input", test);
	Rect winRect;
	winRect.width = 64;
	winRect.height = 128;
	int sum_x = 0;
	int sum_y = 0;
	int count = 0;

	// 开窗检测....
	for (int row = 64; row < test.rows - 64; row += 4) {
		for (int col = 32; col < test.cols - 32; col += 4) {
			winRect.x = col - 32;
			winRect.y = row - 64;
			vector<float> fv;
			Mat testwindows = (test.clone())(winRect);
			get_hog_descriptor(testwindows, fv);
			Mat one_row = Mat::zeros(Size(fv.size(), 1), CV_32FC1);
			for (int i = 0; i < fv.size(); i++) {
				one_row.at<float>(0, i) = fv[i];
			}
			float result = svm->predict(one_row);
			if (result > 0) {
				// rectangle(test, winRect, Scalar(0, 0, 255), 1, 8, 0);
				count += 1;
				sum_x += winRect.x;
				sum_y += winRect.y;
			}
		}
	}

	// 显示box
	winRect.x = sum_x / count;
	winRect.y = sum_y / count;
	rectangle(test, winRect, Scalar(255, 0, 0), 2, 8, 0);
	imshow("object detection result", test);
	imwrite("D:/case02.png", test);
	waitKey(0);
	return 0;

}
相关推荐
小雅痞10 分钟前
[Java][Leetcode middle] 209. 长度最小的子数组
java·算法·leetcode
做时间的朋友。21 分钟前
精准核酸检测
java·数据结构·算法
小何code26 分钟前
人工智能【第10篇】支持向量机SVM:寻找最优分类超平面(长文+代码实现)
人工智能·机器学习·支持向量机
冯诺依曼的锦鲤35 分钟前
从零实现高并发内存池:TCMalloc 核心架构拆解
c++·学习·算法·架构
Thomas_Lee_OR38 分钟前
多Agent路径规划 LaCAM for multi-agent path finding (MAPF)
算法·路径规划·仓储机器人·mapf
一切皆是因缘际会1 小时前
可落地数字生命工程:从记忆厮杀到自我意识觉醒全链路,AGI内生智能硅基生命心智建模
人工智能·深度学习·算法·机器学习·ai·系统架构·agi
nlpming1 小时前
opencode Agent 详解
算法
江南十四行1 小时前
排序算法进阶:直接插入排序(简单排序)与希尔排序
数据结构·算法·排序算法
nlpming1 小时前
opencode System Prompt 构建机制 & AGENTS.md注入机制
算法
nlpming1 小时前
opencode - 安装和配置
算法