_________________________________________________________________________________________________________________________________
批处理(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; //颜色空间的转换 BGR2HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为30个bin,把S通道分为32bin int hbins = 30; int sbins = 32; int histSize[] = { hbins , sbins}; //H的取值范围 0-179 float hranges[]= {0,180}; //S的取值范围 0-255 float sranges [] ={0,256}; const float* ranges [] ={hranges,sranges}; Mat hist2D,histRow,histRowDst; //我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32F int 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; //颜色空间的转换 BGR2HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为30个bin,把S通道分为32bin int hbins = 30; int sbins = 32; int histSize[] = { hbins , sbins}; //H的取值范围 0-179 float hranges[]= {0,180}; //S的取值范围 0-255 float sranges [] ={0,256}; const float* ranges [] ={hranges,sranges}; Mat hist2D,histRow,histRowDst; //我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32F int 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; }
_______________________________________________________________________________________________________________________________
上面已经批处理提取了图像的特征,那么通常我们再做目标识别、检测时,会给训练数据集,准备类标签,下面,继续对上述程序进行拓展。