聞きかじりめも

主にC++やメディア処理技術などに関して気付いたことを書いていきます.ここが俺のメモ帳だ!

画像ファイルのリネーム方法(VisualStudio 2013)

今回のTipsはOpenCVは殆ど関係ない(いや,ちょっと関係あるかも)です.

要件定義

OpenCVで画像処理していると,画像処理結果をちょこっとリネームして保存したいことがよくあります. 今回私がやりたいことは,

ソースファイルと同じディレクトリにファイル名の末尾にインデックス(もしくはそれに準ずるもの)を付け足したい

です.具体的には次のようなやつです.

./img/src1/hoge.png
↓
./img/src1/hoge_nega.png

方法

ここではVisual Studio 2012以降に登場したtr2::sys::pathクラスを使用しようと思うので, 先人の知恵を参考にして組んでみます.

#include <opencv2\opencv.hpp>
#include <filesystem>

using namespace std;
using namespace cv;

int main(void)
{
    // 元画像の読み込み
    string filename;
    cout << "空白を含まないファイルパスを入力してください.(例:img/file_name.png)\n"
        << "\nOriginal Image File Path = ";
    cin >> filename;
    tr2::sys::path path(filename);
    cout << "path:" << path << endl;
    Mat original = imread(path.relative_path().string());

        //      適当な画像処理
        Mat dst = ~original;

    // 表示
    imshow("元画像", original);
    imshow("反転", dst);
    waitKey(0);

    // リネームして保存
    imwrite(path.parent_path() + "/" + path.stem() + "_nega" + path.extension(), dst);

    destroyAllWindows();

    return 0;
}

コンソールに入力するファイルパスにspaceが含まれていると途中までしか認識してくれませんので, ちゃんとASCIIコードで入力するか,ファイル名からspaceを削除するかしましょう. そうでないと,例えばファイルパスが./img/src 1/hoge.pngだとpath./img/srcまでしか読み込んでくれません.

(2015/11/26追記)

上記の方法は日本語入力に対応していません.具体的には,tr2::sys::pathクラスでは認識できているものの,cv::imread()に渡すときにpath.relative_path().string()string型に変換する際にマルチバイト文字列が壊れてしまうようです.従って,内部データをそのまま渡すことによってこの現象を回避します.具体的には

 Mat original = imread(path._Mystr);

と変更するだけでマルチバイト文字にも対応します.