grayscaleのMTLTextureをCoreML/Visionの予測に渡す
機械学習の結果であるmlmodelファイルがあり、それをiOSアプリで使う場合。
Core ML+Visionを用いた物体認識の最小実装 - Qiita
↑通常このような流れでできると思うのだが、画像が白黒のMTLTextureだったので躓いた。
モデルへの入力が画像の場合、
今回はMTLTextureがあるのでまずはそれを変換する必要がある。
これでモデルへ渡せる。
カラーだとこれでいいんだと思う。
今回のケースはこのMTLTextureがgrayscaleの白黒画像だった。pixelFormatは .r8Unorm だと確認できる。
これを使いモデルで予測させると全然期待してない結果を出す。警告などもない。
これがモデル自体の性能なのか?モデル作り直すかなと思っていたのだが、よくよく調べると白黒画像に起因するものだった。
結果から言うと上記のCIImageで色空間(color space)を設定していなかったことが原因だった。

↑一番上が元の白黒画像。
imageAは上記ciImageAを
imageBは上記のオプションで色空間を指定した場合。ちゃんと色空間を設定した白黒画像は赤っぽく表示されることはないんだな、、、覚えておかねば!
なお、imageA,BともciImage作成時に上下反転させているが略。
Core ML+Visionを用いた物体認識の最小実装 - Qiita
↑通常このような流れでできると思うのだが、画像が白黒のMTLTextureだったので躓いた。
モデルへの入力が画像の場合、
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])↑このような感じで予測を実行するのでCIImageかCGImageが欲しい。
//let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try! handler.perform([mlRequest])
今回はMTLTextureがあるのでまずはそれを変換する必要がある。
let ciImageA = CIImage(mtlTexture: mtlTexture, options: nil)↑MTLTextureをCIImageに変換するメソッドがあるので一撃。
これでモデルへ渡せる。
カラーだとこれでいいんだと思う。
今回のケースはこのMTLTextureがgrayscaleの白黒画像だった。pixelFormatは .r8Unorm だと確認できる。
これを使いモデルで予測させると全然期待してない結果を出す。警告などもない。
これがモデル自体の性能なのか?モデル作り直すかなと思っていたのだが、よくよく調べると白黒画像に起因するものだった。
結果から言うと上記のCIImageで色空間(color space)を設定していなかったことが原因だった。
let option = [ CIImageOption.colorSpace: CGColorSpaceCreateDeviceGray() ]↑このようにcolor spaceを設定しておけば意図通りの予測結果が出てきた。
let ciImageB = CIImage(mtlTexture: mtlTexture, options: option)

↑一番上が元の白黒画像。
imageAは上記ciImageAを
let uiImageA = UIImage(ciImage: ciImageA!)このようにUIImageオブジェクトにして表示したもの。そもそもがRGBの色空間に赤の1チャンネルだけのデータがあるから赤っぽくなるんだろう。
imageBは上記のオプションで色空間を指定した場合。ちゃんと色空間を設定した白黒画像は赤っぽく表示されることはないんだな、、、覚えておかねば!
なお、imageA,BともciImage作成時に上下反転させているが略。
スポンサーサイト