画像処理をするにあたって、フォルダ内に入っている全ての画像に処理をしたいということがあります。
それも、画像名を全て手動で入力して読み取るのではなく、フォルダ内に入っている画像を全て自動で取得してくれたら楽だなぁと思いました。
なので、今回は特定のフォルダの中にある「bmp」「png」「jpg」の画像ファイル名を全て取得するプログラムを書いてみました。
ファイル名さえ取得してしまえば、あとはOpenCVのimread関数などに渡すことで、画像を全て読み込んで画像処理をすることが可能です。
今回の環境
・OS : Windows10(64bit)
・Visual Studio 2015 Express
ソースコード自体はWindows APIを一部使っているので、Windows環境での実行が前提となります。
ソースコード
以下のサイトのコードを参考に、特定の拡張子のファイルだけを取得するプログラムを作成しました。
外部サイト:C++言語でディレクトリ内のファイル一覧取得(windows編)
#include <Windows.h> | |
#include <stdexcept> | |
#include <iostream> | |
#include <vector> | |
#include <string> | |
using namespace std; | |
// 入力フォルダ名の指定 | |
string INPUT_FOLDER_NAME = "./input_image/"; | |
// INPUT_FOLDER_NAMEのフォルダ内にある画像名を取得する | |
vector<string> getImageName(string dir_name) { | |
HANDLE hFind; | |
WIN32_FIND_DATA win32fd; | |
std::vector<std::string> file_names; | |
// png,jpg,bmpの拡張子のファイルのみを読み込む | |
std::string extension[3] = {"png" ,"jpg", "bmp"}; | |
for (int i = 0; i < 3; i++) { | |
string search_name = dir_name + "*." + extension[i]; | |
hFind = FindFirstFile(search_name.c_str(), &win32fd); | |
if (hFind == INVALID_HANDLE_VALUE) { | |
continue; | |
} | |
do { | |
if (win32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { | |
} | |
else { | |
file_names.push_back(win32fd.cFileName); | |
} | |
} while (FindNextFile(hFind, &win32fd)); | |
FindClose(hFind); | |
} | |
return file_names; | |
} | |
int main(void) { | |
// ファイル内の画像名の取得 | |
vector<string> file_names = getImageName(INPUT_FOLDER_NAME); | |
// 表示部分 | |
for (auto f : file_names) { | |
cout << f << endl; | |
} | |
return 0; | |
} |
以下のようなフォルダを用意して実行すると、
このようにテキストファイルやフォルダはスキップして画像名だけを取得できていることがわかります。
今回はVisual Studioで実行しましたが、実行時の注意点として「マルチバイト文字セットを使用する」を選択しないと私はビルドで以下のようなエラーが出ました。
エラー C2664 ‘HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)’: 引数 1 を ‘const char *’ から ‘LPCWSTR’ へ変換できません。
文字セットのところから「マルチバイト文字セットを使用する」を選択してビルドするようにしてください。
まとめ
Deep Learningなどをしていると、フォルダ内の全ての画像に対して何らかの前処理などをしたいケースがあると思います。
そういった際には、このようにフォルダ内の全ての画像のファイル名を取得し、読み出して処理を行ったりすることが可能となります。