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;

}
相关推荐
天飓几秒前
基于OpenCV的自制Python访客识别程序
人工智能·python·opencv
lapiii3581 分钟前
图论-代码随想录刷题记录[JAVA]
java·数据结构·算法·图论
Dontla1 小时前
Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须手动添加泛型特征约束?(泛型trait约束)
开发语言·算法·rust
Ttang231 小时前
Leetcode:118. 杨辉三角——Java数学法求解
算法·leetcode
喜欢打篮球的普通人1 小时前
rust模式和匹配
java·算法·rust
java小吕布2 小时前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
杜若南星2 小时前
保研考研机试攻略(满分篇):第二章——满分之路上(1)
数据结构·c++·经验分享·笔记·考研·算法·贪心算法
路遇晚风2 小时前
力扣=Mysql-3322- 英超积分榜排名 III(中等)
mysql·算法·leetcode·职场和发展
Neophyte06082 小时前
C++算法练习-day40——617.合并二叉树
开发语言·c++·算法