A certain engineer "COMPLEX"

開発メモ その41 OpenCVで非ユニコード文字列ファイル名を扱う

Problem


OpenCVSharpOpenCVSharp.Cv2.ImReadメソッドは、内部的には、OpenCVcv::imread関数を呼んでいます。
問題は、OpenCVがユニコード文字列を扱えないため、ANSI文字列しか受け取れないことです。
より正確には、OpenCVSharpからネイティブに自動的にマーシャリングされる際に、System.String、つまりUTF-16からANSI文字列に変換されています。

その際、非ユニコードに変換できない文字列を含むと以下の例外を投げます。

マーシャリングできません: マップできない文字を検出しました。

UTF-16から、ANSIへのマーシャリングは、.NETのソースを見ると、System.String.ConvertToAnsiメソッドを経由し、WideCharToMultiByte関数が呼ばれています。
なので、どうしようもありません。

本当に?

Solution


問題は、下記にように、ファイルパスを渡しているから問題が起きるわけです。


var mat = OpenCvSharp.Cv2.ImRead(filepath);

つまり、下記のように、メモリデータを直接渡し、デコードすれば良いわけです。


var array = File.ReadAllBytes(filepath);
var mat = Cv2.ImDecode(array, ImreadModes.Color);

Cv2.ImDecodeの第2引数は指定が必須です。OpenCvSharp.Cv2.ImReadは本来第2引数がありますが、既定でImreadModes.Colorが設定されるので、同じ値にしておきました。

4 thoughts on “開発メモ その41 OpenCVで非ユニコード文字列ファイル名を扱う

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。