opencv批处理提取图像的特征

来源:互联网 发布:国泰安数据收费吗 编辑:程序博客网 时间:2024/05/01 06:37

_________________________________________________________________________________________________________________________________

批处理(dir/a/s/b)

例:某目录下有a、b、c、d、e、f、g、h、j的图片和一个文件夹JN,里边包含一张图片john.jpg


我们在该目录下的命令行中 输入:dir/b

b:只显示当前目录下文件名及文件夹名

a-d:只是显示该目录下的文件名(没有了文件夹的名)

我们在该目录下的命令行中 输入:dir/a-d/b

S:显示该目录下的文件名和文件夹名,及子目录下的文件名,并显示这些文件的绝对路径

我们在该目录下的命令行中 输入:dir/s/b


我们在该目录下的命令行中 输入:dir/s/a-d/b(由于a-d的作用,文件夹JN没有显示出来)

我们在该目录下的命令行中 输入:dir/s/a-d/b>F:\目录.txt

就会在F盘生成一个文件名为 目录 的.txt文件,该文件包含上面的命令行打出的内容。


—————————————————————————————————————————————————————

第二步:既然已经生成上述文件 目录.txt,然会我们写程序读取这个 目录.txt 即可。

<span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:14px;">#include<iostream>#include<fstream>#include<string>using namespace std;int main(int argc,char* argv[]){if(argc !=2){cerr << "Wrong Argument !" <<endl;return -1;}//定义文件流,只能读取ifstream inPutFile(argv[1],ios::in);if(! inPutFile){cerr << "File Open Erro !" <<endl;return -1;}//读取文件流中的每一行,并赋值给fileName,并在命令行中打印string fileName ;/* 测试读取文件中的每一行*///行数int number = 0;while (getline(inPutFile,fileName)){number ++;cout<<"第"<< number << "行"<< fileName <<endl;}    //注意一定要记得关闭文件流inPutFile.close();return 0;}</span></span></span>

我们编译一下:


我们看一下输出结果:

好的,这样,说明我们读到了每一行。

————————————————————————————————————————————————————

第三步:配置Opencv,然后,读取显示每一幅图片

<span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Microsoft YaHei;font-size:14px;">#include<iostream>#include<fstream>#include<string>using namespace std;#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>using namespace cv;int main(int argc,char* argv[]){if(argc !=2){cerr << "Wrong Argument !" <<endl;return -1;}//定义文件流,只能读取ifstream inPutFile(argv[1],ios::in);if(! inPutFile){cerr << "File Open Erro !" <<endl;return -1;}//读取文件流中的每一行,并赋值给fileName,读取每一幅图像并显示string fileName ;Mat image;while (getline(inPutFile,fileName)){image = imread(fileName,1);namedWindow(fileName,1);imshow(fileName,image);}waitKey(0);    //注意一定要记得关闭文件流inPutFile.close();return 0;}</span></span>


结果:

我们看到我们已经成功把每一幅图像读入到内存中,这样我们就可以求每一幅图像的特征。

—————————————————————————————————————————————————————

第四步:我们计算每一幅图像的直方图特征(当然opencv中sift、surf、densesift等,因为我这里的图片大小不一样,所以我用直方图的特征,使得特征向量的长度一样)

<span style="font-family:Microsoft YaHei;font-size:14px;">#include<iostream>#include<fstream>#include<string>using namespace std;#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>using namespace cv;//计算二维直方图特征Mat hist2d(const Mat& src);int main(int argc,char* argv[]){if(argc !=2){cerr << "Wrong Argument !" <<endl;return -1;}//定义文件流,只能读取ifstream inPutFile(argv[1],ios::in);if(! inPutFile){cerr << "File Open Erro !" <<endl;return -1;}//读取文件流中的每一行,并赋值给fileName,读取每一幅图像并显示string fileName ;Mat image;Mat featureHist;Mat featureHists;while (getline(inPutFile,fileName)){image = imread(fileName,1);//计算二维直方图特征featureHist = hist2d(image);//按行存储每一幅图像的二维直方图特征featureHists.push_back(featureHist);}    //注意一定要记得关闭文件流inPutFile.close();return 0;}Mat hist2d(const Mat& src){Mat hsv;//颜色空间的转换 BGR2HSVcvtColor(src,hsv,CV_BGR2HSV);//把H通道分为30个bin,把S通道分为32binint hbins = 30;int sbins = 32;int histSize[] = { hbins , sbins};//H的取值范围 0-179float hranges[]= {0,180};//S的取值范围 0-255float sranges [] ={0,256};const float* ranges [] ={hranges,sranges};Mat hist2D,histRow,histRowDst;//我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32Fint channels [] ={0,1};calcHist(&hsv,1,channels,Mat(),hist2D,2,histSize,ranges,true,false);//把直方图特征按一行来存储histRow=hist2D.reshape(1,1);//把直方图归一化normalize(histRow,histRowDst,1,0,NORM_L1);return histRowDst;}</span>
这样就把所有的图像的二维直方图特征按行存储在featureHists中。当然可以把二维直方图特征换成自己想要用的任意特征。

—————————————————————————————————————————————————————

第五步:

我们所有图像的颜色直方图存储到.xml文件中,

#include<iostream>#include<fstream>#include<string>using namespace std;#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>using namespace cv;//计算二维直方图特征Mat hist2d(const Mat& src);int main(int argc,char* argv[]){if(argc !=2){cerr << "Wrong Argument !" <<endl;return -1;}//定义文件流,只能读取ifstream inPutFile(argv[1],ios::in);if(! inPutFile){cerr << "File Open Erro !" <<endl;return -1;}//读取文件流中的每一行,并赋值给fileName,读取每一幅图像并显示string fileName ;Mat image;Mat featureHist;Mat featureHists;while (getline(inPutFile,fileName)){image = imread(fileName,1);//计算二维直方图特征featureHist = hist2d(image);//按行存储每一幅图像的二维直方图特征featureHists.push_back(featureHist);}    //注意一定要记得关闭文件流inPutFile.close();/*第五步,把图像特征保存到.xml文件中*/FileStorage fs("C:\\Users\\zhaoyuan001\\Desktop\\test\\dirtest\\x64\\Debug\\da.xml",FileStorage::WRITE);fs<<"featureHists"<<featureHists;fs.release();return 0;}Mat hist2d(const Mat& src){Mat hsv;//颜色空间的转换 BGR2HSVcvtColor(src,hsv,CV_BGR2HSV);//把H通道分为30个bin,把S通道分为32binint hbins = 30;int sbins = 32;int histSize[] = { hbins , sbins};//H的取值范围 0-179float hranges[]= {0,180};//S的取值范围 0-255float sranges [] ={0,256};const float* ranges [] ={hranges,sranges};Mat hist2D,histRow,histRowDst;//我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32Fint channels [] ={0,1};calcHist(&hsv,1,channels,Mat(),hist2D,2,histSize,ranges,true,false);//把直方图特征按一行来存储histRow=hist2D.reshape(1,1);//把直方图归一化normalize(histRow,histRowDst,1,0,NORM_L1);return histRowDst;}
_______________________________________________________________________________________________________________________________

上面已经批处理提取了图像的特征,那么通常我们再做目标识别、检测时,会给训练数据集,准备类标签,下面,继续对上述程序进行拓展。




1 0
原创粉丝点击