画像解析をUnityでやってみよう。4回目です。
前回までで、WebCamTextureの表示を画面いっぱいまで広げることができました。
しかし、デバイスを傾けると画像が歪みます。今回はそのあたりの修正と画質の調整を行い、やっとこさカメラの準備完了です!

デバイスを傾けると画像が歪む問題を修正する

歪んている。。

うん、歪んでいます。横にのびていますね。
そもそも映像はTextureとして扱われているだけなので、斜めにとると、取れた画像をリサイズしている影響が出てしまうっぽいです。

AspectRatioFitter使ってみる

WebCamTextureからwidthとheightが取れるので、RawImageにAspectRatioFitter貼り付けてAspect比固定してしまおうと思って、やってみました。 歪み修正1 歪み修正2

あ、うまくいってる。。
WebCamTextureが内部的にどのような映像を引っ張ってきているのかよくわからなくなってきた。。
でもまたサイズがおかしいです。カメラのアスペクト比と画面のアスペクト比違うっぽいなあ
明らかに四角の大きさが画面と違う。。

AspectRatioFitterのAspectModeをHeightControlWidthに変更してみる

次にAspectRatioFitterのAspectModeをFitInParentにしていたので、今度は縦に伸ばすために、HeightControlWidthに変えてみます。 歪み修正3 歪み修正4 歪み修正5
やった!歪みがなくなって全画面表示ができました!
ちょっと画面からはみ出ているのは、おそらく先ほど確認した通りで、Sceenのアスペクト比と、カメラのアスペクト比が違うからっぽいですね。

少し疑問点も残りますが、とりあえず、カメラの表示がうまくいきました。
途中でしれっと画質の対応もしていました。

画質を指定する

画質をあげるのは簡単で、コンストラクタに指定するだけです。

webCamTexture = new WebCamTexture(Screen.currentResolution.width, Screen.currentResolution.height, 30);

画質をコンストラクタで指定した場合と指定しない場合を比較してみます。 画質指定なし 画質指定あり
やはり指定した方が画質がよくなっています。
しかし、デバイスのカメラアプリと比較すると、WebCamTextureの方が画質が悪いです。
試しに大きな値を指定してインスタンスを作成しても、それほどの変化はみられませんでした。
画質が最重要なアプリでは、WebCamTextureはおそらく使用しない方が良いでしょう。
カメラのAssetもいろいろありますし、最悪ネイティブ側でカメラを起動して画像を取得するというアプローチも検討すべきかもしれません。
今回は、これで十分なので、WebcamTextureで進めます。

まとめ

カメラの表示だけで結構試行錯誤してしまいました。
WebCamTexture、正直使いづらい。。使う場面が想定と違うのでしょうか。。。
解消できない問題は画質の悪さです。明らかにデバイスのカメラの画質より画質が落ちるので、先ほども記載したとおり、 画質が優先されるアプリにおいて、WebCamTextureは使用しないほうが良さそうです。
他のAssetなどを試していった方が良いかもしれませんね。

最後にコードを

public class DeviceCamera : MonoBehaviour
{    
    private RawImage cameraImage;
    private WebCamTexture webCamTexture;
    private AspectRatioFitter aspectRatioFitter;

    void Awake()
    {
        cameraImage = GetComponent<RawImage>();
        aspectRatioFitter = GetComponent<AspectRatioFitter>();
    }

    void Start()
    {
        webCamTexture = new WebCamTexture(Screen.currentResolution.width, Screen.currentResolution.height, 30);        
        cameraImage.texture = webCamTexture;        
        if (Application.platform == RuntimePlatform.IPhonePlayer)
        {   
            cameraImage.rectTransform.localScale = new Vector3(1,-1,1);                        
        }
        webCamTexture.Play();
    }

    private void Update()
    {
        if (webCamTexture?.isPlaying ?? false)
        {            
            transform.localEulerAngles = new Vector3(0, 0, -1 * (float) webCamTexture.videoRotationAngle);            
            aspectRatioFitter.aspectRatio = (float)webCamTexture.width / (float)webCamTexture.height;            
            
        }        
    }
}

これをRawImageのコンポーネントに貼り付ければ多分動きます。
あと.NET4.6にしてしまっているので、お使いの環境に合わせてコードを修正してください。
それからAspectRatioFitterも貼ってね。
次回からはいよいよOpenCVを使った画像変換にチャレンジです。
さようなり〜