LoginSignup
9
7

More than 5 years have passed since last update.

OpenCV for UnityでwebCamTextureToMatできない(WebCamTextureとMatのサイズが違う?)

Last updated at Posted at 2016-06-25

OpenCV for Unityを使ってウェブカメラの画像をいじろうとしたところ、WebCamTextureをMatに変換するときにエラーが出たため、その時のメモ
※ ビギナーのためコードが汚いと思いますが、ご指摘あればいただけると嬉しいです。

利用環境:Unity5.3, OpenCV for Unity 2.0.1(OpenCV 3.1.0)

問題:WebCamTextureとMatのサイズが違うと言われる

Unity
void Start() {
  webCamTexture = new WebCamTexture(WebCamTexture.devices[0].name);
  webCamTexture.Play();

  mat = new Mat(webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);
  colors = new Color32[webCamTexture.width * webCamTexture.height];
  texture = new Texture2D(webCamTexture.width, webCamTexture.height);

  GetComponent<Renderer> ().material.mainTexture = texture;
}

void Update() {
  Utils.webCamTextureToMat(webCamTexture, mat, colors); // ArgumentException: The output Mat object has to be of the same size

  // 以下Mat処理
}
}

という風に、webCamTextureToMatする時に「Matを同じサイズにしろ」と言われます。
Mat宣言するときにWebCamTextureからwidthとheightを持ってきてるのになんでや。。?

原因:WebCamTexture.widthが16と出力される

なにやら、WebCamTexture.didUpdateThisFrame == falseの状態でWebCamTexture.widthWebCamTexture.heightの値を取得しようとすると(16, 16)で出力されるらしい。そのためmatのサイズが(16, 16)になっていた。

WebCamTexture.widthの値自体は正常なので、webCamTextureとmatの間にサイズの違いが生じていた模様。

ちなみに下記の参考URLではiOSへのビルドに限って起こるUnity自体のバグと書かれているけど、自分の場合は他のプラットフォームにswitchしても生じたので、そこのところは謎。

参考URL
https://issuetracker.unity3d.com/issues/ios-webcamtexture-dot-width-slash-height-always-returns-16

解決法:WebCamTexture.didUpdateThisFrame == trueになるまで待つ

WebCamTexture.didUpdateThisFrame == trueになるまでmatの宣言を待ちつつ、Utils.webCamTextureToMat(webCamTexture, mat, colors);はmatが宣言されるまで実行しないようにしたところ、一応問題は解決した。

Unity
void Start() {
  webCamTexture = new WebCamTexture(WebCamTexture.devices[0].name);
  webCamTexture.Play();
  StartCoroutine (init ());
}

private IEnumerator init (){
  if(webCamTexture.width <= 16){ 
    while(!webCamTexture.didUpdateThisFrame){ 
      yield return new WaitForEndOfFrame(); 
    } 
    webCamTexture.Pause ();
    colors = webCamTexture.GetPixels32 ();
    webCamTexture.Stop ();

    yield return new WaitForEndOfFrame ();
    webCamTexture.Play(); 

    // 宣言
    texture = new Texture2D(webCamTexture.width, webCamTexture.height);
    mat = new Mat(webCamTexture.height, webCamTexture.width, CvType.CV_8UC4);

    GetComponent<Renderer> ().material.mainTexture = texture;
  }
}

void Update() {
  if (webCamTexture.didUpdateThisFrame && mat != null) {
    Utils.webCamTextureToMat (webCamTexture, mat, colors);

    // 以下Mat処理
  }
}
9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7