ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unity] 유니티 OpenCV Mat 과 Texture2D 변환
    Unity 2020. 4. 1. 20:39

    유니티 프로젝트에서 C#으로 매핑된 OpenCV를 사용하고 있다. OpenCV에서는 기본적인 버퍼로 Mat를 사용하여 여러 가지 작업이 이루어지는데, 유니티 게임엔진 내부에서 렌더링을 할 때는 Texture형태를 많이 사용하기에 이 둘 사이를 오가야할 경우가 많이 있다. 예를 들어 작업이 끝난 이미지를 화면에 뿌린다던지, 반대로 화면의 이미지를 가지고 와서 OpenCV로 뭔가 처리를 해야 하는 경우가 빈번하게 발생한다. 익숙하지 않은 툴과 라이브러리로 작업을 하다 보니 둘 사이의 변경에 시행착오를 많이 겪어 이를 남겨본다.

     

     

    Texture2D to Mat

     

    이 작업을 위해 유니티에 포팅된 OpenCV는 Utils.texture2DToMat이라는 함수를 제공한다. 사용방법은 간단하지만 주의할 점이 있는데, Mat와 Texture2D의 컬러 포맷과 가로 세로 길이가 동일해야 한다는 점이다. 조금이라도 틀리면 카피할 바이트가 모자란다거나 반대로 크기가 맞지 않는다는 에러와 함께 기능이 수행되지 않는다. 다음은 예제 코드이다.

     

    // 640x480 Texture 생성
    Texture2D texture = new Texture2D(640, 480, TextureFormat.RGBA32, false);
    
    // 이미지 로드 등 texture의 내용을 채워넣는 작업 
    ...
    ...
    
    // Matrix 할당
    // width, height가 아닌 height, width 순서임을 주의!!
    Mat mat = new Mat(texture.height, texture.width, CvType.CV_8UC4);
    
    // 변환
    Utils.texture2DToMat(texture, mat);

     

    변환이 안되어서 삽질을 계속 했는데, new Mat()의 첫째 인자를 width로 주고 두 번째 인자를 height로 주었었다. 정신줄늘 놓고 있었던게 큰 원인이긴 하지만 헷갈릴 수 있으므로 주의하기를 바란다. Mat의 첫째 인자는 rows이므로 높이가 되고, 둘째 인자는 cols이므로 넓이가 된다.

     

     

    Mat to Texture2D

     

    이 작업을 위해 유니티에 포팅된 OpenCV에 Utils.MatToTexture2D 그리고 Utils.fastMatToTexture2D 함수가 제공된다. 다음은 작업이 끝난 Mat를 신규 텍스처에 담고 이를 게임오브젝트에 표시하는 예제이다.

     

    // 640x480 Texture 생성
    Texture2D texture = new Texture2D(640, 480, TextureFormat.RGBA32, false);
    
    // 변환
    Utils.fastMatToTexture2D(mat, texture);
    
    // 화면에 표시
    Renderer rend = gmaeObject.GetComponent<Renderer>();
    if (rend != null)
    {
    	rend.material.mainTexture = texture;
    }
    

     

    주의할 점은 Mat의 컬러 포맷이 CV_8UC4를 가정하고 있다는 점이다. 그래서 Texture2D도 이와 같은 크기를 가지도록 RGBA32로 생성한 것이다. 만약 RGB등 다른 포맷일 경우 해당 포맷으로 Texture2D를 생성해야 한다.

     

     

    Fin.

     

     

     

    반응형

    댓글

Calvin's Memo