본문 바로가기
유니티3D[Unity3D]

[OpenCV For Unity] AR Glass에 OpenCV 기반 Image Tracking 구현

by 은유지니 2023. 4. 3.

개발 환경

  • Unity 2020.3.20f1 버전
  • OpenCV For Unity
  • NReal Light AR Glass(CameraTexture 활용 가능한 AR Glass)

OpenCV For Unity에는 WebCam 텍스쳐를 이용하여 특정 이미지를 인식할 수 있는 예제가 존재한다.

이 원리를 이용하여 AR Glass의 카메라를 이용, AR 환경 내에 Image Tracking을 구현해보려고 한다.

우선 NReal을 사용하여 NReal SDK의 NRRGBCamTexture를 WebCamTexture 대신으로 설정하였다.

다른 AR Glass를 이용하더라도 우선 CamTexture를 가져올 수 있는 라이브러리가 있어야 응용이 가능하다.


OpenCV for Unity의 WebCam Texture예제에서는 다음과 같은 AR 오브젝트를 사용한다.(빨간 큐브 가로 세로는 각 1m)

Markerless AR 기본 오브젝트(축 제외 가로 세로 길이 1m)

 

기존 OpenCV  WebCamTextureToMat 예제의 구조

  • 카메라 텍스쳐 이용.
  • 1m x 1m 오브젝트가 현재 타겟의 “크기”에 맞게끔 거리 조정.
  • 즉, 타겟이 위치한 곳에 AR 오브젝트가 위치하지 않는 경우가 다수.

타겟 이미지에 맞게 배치된 1m x 1m 오브젝트를 옆에서 본 모습

 

AR Image Tracking을 구현하기 위해서는 타겟이미지와 AR 오브젝트의 위치가 일치해야만 한다. (100% 일치는 물론 힘들겠지만 당연히 오차율이 작을수록 좋겠다.) 하지만 OpenCV는 오브젝트의 위치를 타겟이미지와 일치시켜주지 않아 위치를 맞춰주는 로직을 추가하였다.

사용 수식은 다음과 같다.

타겟 이미지의 실제 위치를 구하기 위한 수식 참조 그림

위 그림을 이용하면 아래와 같은 수식이 나오고,

ImgDist : ImageRealSize = D : 100cm

x/imgDist = (obj.x – cam.x) / D

z/x = (obj.z – cam.z) / (obj.x – cam.x)

y/z = (obj.y – cam.y) /(obj.z – cam.z)

이를 정리하면 다음과 같이 계산할 수 있다.

ImgDist = ImageRealSize* D / 100cm

x = ((obj.x – cam.x) / D) * imgDist
y = (obj.y – cam.y) * z /(obj.z – cam.z)
z = (obj.z – cam.z) * x / (obj.x – cam.x)

ImageRealSize는 public value로 직접 입력해주어야하는 부분.

D, Obj와 Cam의 x, y, z는 opencv 예제를 통해 이미 아는 값이다.

 

이를 유니티 C# 코드로 구현하면 다음과 같다.

public Vector3 GetARObjectPos(float ImgRealSize, Vector3 ARCamPos, Vector3 ARObjPos)
{
    Vector3 ARObjPosFromCam = ARObjPos - ARCamPos;
    float dist = Vector3.Distance(ARCamPos, ARObjPos); //opencv에 계산된 AR object 거리
    float ImgDist = ImgRealSize * 0.01f * dist; // 실제 이미지까지 거리
    float ratio = ImgDist / dist; //거리 비율 계산

    float x = ARObjPosFromCam.x * ratio;
    float y = (ARObjPosFromCam.y / ARObjPosFromCam.x) * x; 
    float z = (ARObjPosFromCam.z / ARObjPosFromCam.x) * x;

    Vector3 ARObjPosFromCam_Real = new Vector3(x, y, z);
    Vector3 ARObjPos_Real = ARCamPos + ARObjPosFromCam_Real;

    return ARObjPos_Real;
}

이로써, 실제 타겟이미지의 위치를 계산함으로써 AR Object가 위치할 진짜 위치를 찾을 수 있다.


해당 로직은 정사각형 타겟 이미지 기준으로 계산된 로직입니다.

만약 이미지의 가로, 세로 길이가 다르다면 위 로직을 이용하여 수식을 수정해서 충분히 이용가능할 것 입니다.