【徒手写机器学习算法】再谈数据源:从普通图片到Cifar-10(使用C++)
【徒手写机器学习算法】再谈数据源:从普通图片到Cifar-10(使用C++)
在本系列的第一篇文章里,关于机器学习的数据源的问题被一笔带过(使用csv格式的数据),这一篇文章我会给出关于图片数据制作的两个示例.
本文完整代码在:https://github.com/Luomin1993/Cell_For_Img
所需前提
在开始之前我说一下需要准备的东西:
- g++编译器(废话..)
- opencv2或opencv3
- Cifar-10数据集(待会儿会说)
又是Lena
你可能会想,怎么又是这个女人,这是一个经典的图像处理的素材:
关于她:
谁是Lena? 最早使用这张相片作测试样本的是谁? 还有这张相片是怎么来的? 人人认识Lena,这些问题大家都很好奇,却很少人知道解答。Lena照片的来源是花花公子(Playboy)杂志1972年11月份玩伴女郎Lena全身裸照的中央插页,在这期杂志中使用了“Lenna”的拼写,而实际莉娜在瑞典语中的拼写是“lena”。
1973年6,7月间,南加州大学信号图像处理研究所的副教授Alexander和学生一起,为了一个同事的学会论文正忙于寻找一副好的图片。他们想要一副具有良好动态范围的人的面部图片用于扫描。不知是谁拿着一本Playboy走进研究室。由于当时实验室里使用的扫描仪(Muirhead wirephoto scanner)分辨率是100行/英寸,试验也仅仅需要一副512X512的图片,所以他们只将图片顶端开始的5.12英寸扫描下来,切掉肩膀一下的部分。
言归正传,我们来提取这个图像的直方图,并将直方图进行PAC降维处理,然后保存到csv文件供机器学习数据使用。
void saveMat(cv::Mat inputMat,char* filename)
{FILE* fpt = fopen(filename,"a");int rows = inputMat.rows;int clos = inputMat.cols;for (int i = 0; i < rows;i++){for(int j = 0;j<clos;j++){if (j < clos-1)fprintf(fpt,"%f,",inputMat.at<float>(i,j));elsefprintf(fpt,"%f\n",inputMat.at<float>(i,j));}}fclose(fpt);
}void saveMatAsVec(cv::Mat inputMat,char* filename)
{FILE* fpt = fopen(filename,"a");int rows = inputMat.rows;int clos = inputMat.cols;for (int i = 0; i < rows;i++){for(int j = 0;j<clos;j++){/*if (j < clos-1)fprintf(fpt,"%f,",inputMat.at<float>(i,j));elsefprintf(fpt,"%f\n",inputMat.at<float>(i,j));*/fprintf(fpt,"%f,",inputMat.at<float>(i,j));}}fprintf(fpt,"\n");fclose(fpt);
}void save_pca_vec_to_csv_file(cv::Mat img,char* filename)
{int floor_num = 120; //cvtColor(img, img, CV_RGB2GRAY);PCA pca(img, Mat(), CV_PCA_DATA_AS_COL, floor_num); //图片大小为400*362 //这里按COL的方式降维,保证列数不便,行数降低到120层 //所以可以发现打印的均值的规格为1*362 cout << "均值的规格:" << pca.mean.size() << endl;//均值 cout << "特征值的规格:"<<pca.eigenvalues.size() << endl;//特征值 cout <<"特征向量的规格:" <<pca.eigenvectors.size() << endl;//特征向量 Mat dst = pca.project(img);//映射新空间 //cout << dst; //Mat src = pca.backProject(dst);//反映射回来 saveMatAsVec(dst,"./color.csv");
}
关于PAC降维:主成分分析,是一种统计方法,通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。
- 将原始数据按列组成nnn行m" role="presentation" style="position: relative;">mmm列矩阵XXX
- 将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值
- 求出协方差矩阵C=1mXXT" role="presentation" style="position: relative;">C=1mXXTC=1mXXTC=\frac{1}{m}XX^\mathsf{T}
- 求出协方差矩阵的特征值及对应的特征向量
- 将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P
- Y=PXY=PXY=PX即为降维到kk<script type="math/tex" id="MathJax-Element-6">k</script>维后的数据
编译运行方式:
root@master:# g++ -I/usr/local/opencv2/include/ -o color_feature color_feature.cpp -L/usr/local/opencv2/lib -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core -lopencv_nonfree
root@master:# ./color_feature lena.jpg
关于Cifar-10
该数据集共有60000张彩色图像,这些图像是32*32,分为10个类,每类6000张图。这里面有50000张用于训练,构成了5个训练批,每一批10000张图;另外10000用于测试,单独构成一批。测试批的数据里,取自10类中的每一类,每一类随机取1000张。抽剩下的就随机排列组成了训练批。注意一个训练批中的各类图像并不一定数量相同,总的来看训练批,每一类都有5000张图。
它的下载地址:http://www.cs.toronto.edu/~kriz/cifar.html
现在让我们用opencv读取它的二进制格式数据,再将其转化为图片,然后我们就可以用上面的特征提取程序来提取特征向量到文本文件。
int main(int argc, char *argv[])
{//QCoreApplication a(argc, argv);FILE *fpr = fopen("./cifar-10-batches-bin/data_batch_1.bin","rb");//打开cifar-10的一个文件if(fpr==NULL){cout<<"文件打开失败!"<<endl;fclose(fpr);return 0;}int labelr(0);//存labelchar buffer = 0;//缓存int yrow = 100;//行图片数int xcol = 100;//列图片数int image_num;//Mat image(32*yrow,32*xcol,CV_8UC3,Scalar::all(0));//opencv 的Mat对象,用来存图片的像素矩阵//重点是这个循环//Cifar file stream:[[label:(R),(G),(B)],[label:(R),(G),(B)],[label:(R),(G),(B)],[label:(R),(G),(B)]...]//std::vector<Mat> RES;for(int y = 0;y<=yrow-1;y++)//循环行图片{for(int x = 0;x<=xcol-1;x++)//列图片{Mat image(32,32,CV_8UC3,Scalar::all(0));//opencv 的Mat对象,用来存图片的像素矩阵fread(&labelr,sizeof(char),1,fpr);//获取每张图片前的label 不要忘记了cout<<"label:"<<labelr<<endl;for(int b = 2;b>=0;b--)//循环RGB颜色{for(int j = 0;j<32;j++)//循环行像素{for(int i = 0;i<32;i++)//循环列像素{fread(&buffer,sizeof(char),1,fpr);image.at<Vec3b>(j,i)[b] = buffer;//用at来获取数据 ,还有其他办法,大家可以找找}}}imwrite("./CIFAR10/"+std::to_string(x*y)+".jpg", image);//RES.push_back(image);//show the image one by one//if(y==0 && x==0){imshow("1",image);waitKey(100);}//sleep(3);}}//imshow("1",RES[10]);waitKey(100000);fclose(fpr);return 0;
}
提取成果:
【徒手写机器学习算法】再谈数据源:从普通图片到Cifar-10(使用C++)相关推荐
- 数据结构与算法--再谈递归与循环(斐波那契数列)
再谈递归与循环 在某些算法中,可能需要重复计算相同的问题,通常我们可以选择用递归或者循环两种方法.递归是一个函数内部的调用这个函数自身.循环则是通过设置计算的初始值以及终止条件,在一个范围内重复运算. ...
- 机器学习笔记—再谈广义线性模型
前文从线性回归和 Logistic 回归引出广义线性回归的概念,很多人还是很困惑,不知道为什么突然来个广义线性回归,有什么用?只要知道连续值预测就用线性回归.离散值预测就用 Logistic 回归不就 ...
- 使用python写机器学习算法遇到的问题
问题:NameError: name 'array' is not defined 解决方法:导入numpy中的array库 import numpy as np group=np.array([[1 ...
- 【机器学习基础】数学推导+纯Python实现机器学习算法1:线性回归
很多同学在学习机器学习的时候,理论粗略看一遍之后就直接上手编程了,非常值得表扬.但是他不是真正的上手写算法,而是去直接调用 sklearn 这样的 package,这就不大妥当了.笔者不是说调包不好, ...
- 【Machine Learning系列】带你快速学习十大机器学习算法
前言 机器学习算法是一类用于从数据中学习模式和规律的算法.这些算法可以通过训练样本的输入和输出来推断出模型的参数,然后用于预测新的未知数据. 文章目录 前言 机器学习算法 1. 线性回归算法 Line ...
- etc的常见算法_谈常用的几个机器学习算法,学懂算法也可以这么简单!
本文的目的,是务实.简洁地盘点一番当前机器学习算法.文中内容结合了个人在查阅资料过程中收集到的前人总结,同时添加了部分自身总结,在这里,依据实际使用中的经验,将对此类模型优缺点及选择详加讨论 主要回顾 ...
- 7 个小仙女花3年时间写了一本1200页的机器学习算法手册(限时开放下载)
今天这篇文章不谈技术,给大家分享一些干货!首先来聊聊NLP.搜索与推荐领域的画风清奇的公众号 夕小瑶的卖萌屋.公号的作者基本都是 妹子,不仅长得好看,而且实力硬核,还会画画. 这些妹子们毕业于北大.中 ...
- 【字符串算法1】 再谈字符串Hash(优雅的暴力)
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...
- 经典算法研究系列:八、再谈启发式搜索算法
经典算法研究系列:八.再谈启发式搜索算法 作者:July 二零一一年二月十日 本文参考: I. 维基百科. II. 人工智能-09 启发式搜索. III.本BLOG内,经典算法研究系列:一.A ...
最新文章
- 《深入理解Spring Cloud与微服务构建》出版啦!
- SpringBoot中通过自定义缓存注解(AOP切面拦截)实现数据库数据缓存到Redis
- 002 python准备做题的一些准备
- CesiumLab V1.3 新功能 MAX场景处理(免费Cesium处理工具集)
- C++new和delete实现原理(汇编解释)
- 列表,元组和range
- 【正则表达式】IPv4地址的正则匹配
- 开源框架Struts:FormBean滴那些事儿
- 三元运算符最终结果的数据类型
- 休闲策略游戏源码荒野总动员H5+安卓+IOS三端源码
- kettle官网下载
- 基于wincc的虚拟电梯设计_PLC基于WinCC的四层电梯监控系统设计+梯形图
- PHP实现队列及队列原理
- 计算机本地连接怎么找不到了,电脑本地连接不见了该怎么办
- document image inpaint
- http上传文件流程 使用winlnet
- 3.1.hole_behind_comprehensive_teaching_complex 综教楼后的那个坑
- tar分卷压缩/解压大文件
- Vue2 的 diff 算法
- 金蝶云的企业数字化转型之道:从ERP到EBC,从竞争到共生