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;

}
相关推荐
ZZZ_O^O30 分钟前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
CV-King1 小时前
opencv实战项目(三十):使用傅里叶变换进行图像边缘检测
人工智能·opencv·算法·计算机视觉
代码雕刻家1 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain1 小时前
算法 | 位运算(哈希思想)
算法
jndingxin3 小时前
OpenCV视频I/O(14)创建和写入视频文件的类:VideoWriter介绍
人工智能·opencv·音视频
Kalika0-03 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20243 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh5 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy5 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java5 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode