上次例程中,介紹了Opencv例程中FileStorage 的基本用法,包括自定義類型的讀寫操作。這裏做一個擴展,介紹Opencv中另外一個例程(EXAMPLE) imagelist_creator,它通過FileStorage 實現文件夾中圖片的掃描,創建一個xml的文件列表,這個功能對於需要遍歷讀取一個文件夾中的所有圖片文件十分管用,使用也相當方便。
我們先來看下例程中的程序如何使用。
可以看出如果直接使用例程中的程序,我們需要手動一個一個文件名輸入,這將會很麻煩,特別是當圖片量很大時,這是個不可能的工作。觀察源代碼中操作可以發現,FileStorage其實是通過main函數的av參數傳遞文件名,那如果我們有一個文件事先存儲了圖片文件名,要輸入到FileStorage中就會十分方便,利用ifstream讀一個文件名,在利用FileStorage寫一個文件名,則這個例程的第二個參數可以換成一個存儲了圖片文件名的文本文件。那麼如何生成這樣的一個txt文件呢?幸運地是,dos命令提供了這樣的操作。
輸入以上命令,並可以在目錄找到一個txt文件,打開如下圖所示,F:\image_set文件夾下所有的圖片文件名都保存到test.txt中了。
現在對例程程序進行一些修改,代碼如下
/*this creates a yaml or xml list of files from the command line args
*/
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <string>
#include <iostream>
#include <fstream>
using std::string;
using std::cout;
using std::endl;
using namespace cv;
static void help(char** av)
{
cout << "\nThis creates a yaml or xml list of files from the command line args\n"
"usage:\n./" << av[0] << " imagelist.yaml *.txt\n"
<< "Try using different extensions.(e.g. yaml yml xml xml.gz etc...)\n"
<< "This will serialize this list of images or whatever with opencv's FileStorage framework" << endl;
}
int main(int ac, char** av)
{
if (ac != 3)
{
help(av);
return 1;
}
string outputname = av[1];
Mat m = imread(outputname); //check if the output is an image - prevent overwrites!
if(!m.empty()){
std::cerr << "fail! Please specify an output file, don't want to overwrite you images!" << endl;
help(av);
return 1;
}
string filename = av[2]; // txt文件名
std::ifstream fstr(filename); // 利用ifstream對文件中的字符串進行讀取
if(!fstr.is_open())
{
std::cerr<<"failed to open an input file"<<endl;
return 1;
}
string imagename;
FileStorage fs(outputname, FileStorage::WRITE);
fs << "images" << "[";
while(fstr>>imagename){ // 讀入一個文件名
fs << imagename; //寫入到FileStorage風格的xml,yaml等格式中
}
fs << "]";
return 0;
}
下面測試下效果,在cmd輸入如下命令打開imagelist.yaml,如下圖所示
可以看出,這種方法是有效。不過還是會覺得有點繁瑣,因爲需要在cmd中先,輸入命令生成一個txt的文件,再利用imagelistcreate程序對其處理,生成FileStorage風格的文件存儲,有沒有什麼方法讓這個過程更加簡單嗎?答案是有的,由於整個過程我們只需要輸入命令行操作,很容易的,我們可以通過批處理來簡化我們的操作。
具體命令如下:
@echo off
dir /b F:\image_set\*.jpg >>imagelist.txt
F:\opencvbuild\op248\build\bin\Debug\cpp-example-imagelist_creator imagelist.xml imagelist.txt
這裏使用imagelistcreate的絕對路徑,這樣可以在任意目錄下運行,並在該目錄下生成yaml格式的文件。如果需要生成其他文件夾的圖片列表,只需改下文件夾的路徑就可以。另外,如果只需要文件夾中的一部分文件而不是全部文件,比如left開頭的一系列文件,那要怎麼做呢?這個也簡單,只需要更改dir 命令即可,
dir /b F:\image_set\left*.jpg >>imagelist.txt
再稍微修改下,加上上一幅,下一幅控制,便可以做出一個簡單的圖片瀏覽器