Forum
2019.03.25
카메라 텍스처 가져오는 법에 대해서 아시는 분 계신가요?
-
ARcore SDK를 이용해서 AR 프로젝트를 진행하고 있는데요.
ARcore가 안드로이드 카메라를 이용해 실세계의 화면을 가져오고 그 곳에 증강 오브젝트를 배치하는데
저는 여기서 증강오브젝트를 포함하지 않는 실세계의 화면만을 가진 텍스처를 얻고자합니다.
그래서 ARCore API를 잘 찾아보니
Frame.CameraImage.Texture를 찾아서 사용하고 있었는데.. 이게 유니티 에디터 상에서만 동작을 하고
안드로이드 폰으로 빌드를 하니 동작을 하지 않는 문제가 있었습니다.
Texture가 null값이 넘어오고 있었는데요. 더 찾아보니.. CPU에 대한 접근 권한이 없다는 것 같았습니다.
이에조금더 찾아보니 AcquireCameraImageBytes() 라는 것을 찾게되어 이를 토대로 진행을 하였습니다.
하지만 이미지 반환 형태가 YUV 포맷이여서 RGB 포맷으로 변환하는 방법을 찾는 노력을 했습니다.
노력 끝에.. RGB 포맷으로 변환하고 원하는 형식을 얻어 에디터 상에서 확인해보니 원하는 결과가 나왔지만,
위와 동일하게 안드로이드 폰에서는 다르게 동작을 했습니다.
에디터 상에서는 정상적으로 제가 원하는 RGB형태의 텍스처가 등장했지만, 노트 9에서는 회색의 이미지가 추출되었습니다.
이 원인을 아시거나.. 증강오브젝트를 제외한 카메라 텍스처를 얻어보신 경험이 있으신 분이 계시다면 도움을 얻고 싶습니다.
아래는 제 전체 소스코드입니다.
ARCore 샘플 씬에 캔버스- RawImage 오브젝트에 해당 스크립트를 추가하고 테스트 한 내용입니다.
namespace GoogleARCore
{
using System;
using UnityEngine;
using UnityEngine.UI;
public class TestFrameCamera : MonoBehaviour
{
private Texture2D m_TextureRender;
private void Update()
{
using (var image = Frame.CameraImage.AcquireCameraImageBytes()) {
if(!image.IsAvailable)
{
return;
}
_OnImageAvailable(image.Width, image.Height, image.Y, image.Width * image.Height);
}
}
private void _OnImageAvailable(int width, int height, IntPtr pixelBuffer, int bufferSize)
{
m_TextureRender = new Texture2D(width, height, TextureFormat.RGBA32, false, false);
byte[] bufferYUV = new byte[width * height * 3 / 2];
bufferSize = width * height * 3 / 2;
System.Runtime.InteropServices.Marshal.Copy(pixelBuffer, bufferYUV, 0, bufferSize);
Color color = new Color();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
float Yvalue = bufferYUV[y * width + x];
float Uvalue = bufferYUV[(y / 2) * (width / 2) + x / 2 + (width * height)];
float Vvalue = bufferYUV[(y / 2) * (width / 2) + x / 2 + (width * height) + (width * height) / 4];
color.r = Yvalue + (float)(1.37705 * (Vvalue - 128.0f));
color.g = Yvalue - (float)(0.698001 * (Vvalue - 128.0f)) - (float)(0.337633 * (Uvalue - 128.0f));
color.b = Yvalue + (float)(1.732446 * (Uvalue - 128.0f));
color.r /= 255.0f;
color.g /= 255.0f;
color.b /= 255.0f;
if (color.r < 0.0f)
color.r = 0.0f;
if (color.g < 0.0f)
color.g = 0.0f;
if (color.b < 0.0f)
color.b = 0.0f;
if (color.r > 1.0f)
color.r = 1.0f;
if (color.g > 1.0f)
color.g = 1.0f;
if (color.b > 1.0f)
color.b = 1.0f;
color.a = 1.0f;
m_TextureRender.SetPixel(width - 1 - x, y, color);
}
}
m_TextureRender.Apply();
this.GetComponent
().texture = m_TextureRender;
}
}
}
- Replies
-
프로젝트를 여시고 대부분의 블랙처리 혹은 오브젝트 객체에 보시면 'background' 와 유사한 객체가 있을 것 입니다.
AR 기본적인 뼈대는 이러한 외부 카메라 영상을 뒤에 background로 놓고 그 위에 오브젝트를 매칭 시키는 것 입니다. background에 쉐이더나 메테리얼 혹은 스크립트를 참고해보세요.
또한 이러한 부분이 익숙하지 않다면 모바일 카메라 영상을 랜더링하는 소스를 참고하시면 됩니다.
위의 코드는 최종이미지가 결합된 마지막 카메라의 프레임 이미지를 텍스쳐에 넣는 것 입니다.
이럴 경우 이미지 레이어가 모두 합쳐져 있기에 원하시는 결과를 얻으실 수 없습니다.dntjdgh02 2019.03.25 -
답변 감사드립니다. 저도 말씀하신 방법으로 메터리얼의 텍스처를 받아오려고 노력했었는데요.
에디터 상에서는 정상적으로 동작하지만, 모바일 폰으로 빌드시 안 되는 문제가 있었습니다.kmin729 2019.03.25
