기억저장고

[Unity] 키넥트(Kinect V2) Depth Camera 이미지 세팅하는법 본문

Unity

[Unity] 키넥트(Kinect V2) Depth Camera 이미지 세팅하는법

기억해조 2024. 3. 22. 19:00

1. 키넥트 Window Unity Pro 패키지 설치
[키넥트 기본앱 - 키넥트 동작 확인용]
https://www.microsoft.com/en-us/download/details.aspx?id=44561


[키넥트 유니티패키지 - 유니티 개발용]
https://learn.microsoft.com/ko-kr/windows/apps/design/devices/kinect-for-windows

 

Kinect for Windows - Windows apps

Azure Kinect 개발자 키트에 대한 리소스 및 도구입니다.

learn.microsoft.com

2. 코드 작성

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Windows.Kinect;
using UnityEngine.UI;

public class KinectColorDepth : MonoBehaviour
{
    private KinectSensor sensor;
    private MultiSourceFrameReader frameReader;

    // Depth 값을 표시할 텍스처 크기
    private const int depthWidth = 512;
    private const int depthHeight = 424;

    private ushort[] depthData = new ushort[depthWidth * depthHeight];
    private byte[] depthBytes = new byte[depthWidth * depthHeight * 4]; // RGBA 값

    [Header("색상 Graident")]
    public Gradient gradient;

    [Header("결과값")]
    public Texture2D resultTexture;
    public RawImage resultImg;
    private void Awake()
    {
        resultTexture = new Texture2D(depthWidth, depthHeight, TextureFormat.RGBA32, false);
        resultImg.texture = resultTexture;
    }

    private void Start()
    {
        StartKinect();
    }

    private void Update()
    {
        UpdateKinect();
    }

    private void StartKinect()
    {
        sensor = KinectSensor.GetDefault();
        if (sensor != null)
        {
            sensor.Open();
            frameReader = sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color | FrameSourceTypes.Depth);
        }
    }

    private void UpdateKinect() 
    {
        var pMultiSourceFrame = frameReader.AcquireLatestFrame();

        if (pMultiSourceFrame != null)
        {
            using (DepthFrame depthFrame = pMultiSourceFrame.DepthFrameReference.AcquireFrame())
            {
                if (depthFrame != null)
                {
                    depthFrame.CopyFrameDataToArray(depthData);

                    // Depth 값을 컬러로 변환하고 텍스처에 적용
                    CreateDepthTexture();
                }
            }
        }
    }

    private void CreateDepthTexture() 
    {
        for (int i = 0; i < depthData.Length; i++)
        {
            ushort depth = depthData[i];
            float normal = (depth >= ushort.MaxValue ? 1 : (depth / 2048f)); // Depth 값 정규화

            //Depth에 따라 Color 값 변경
            Color keyColor = gradient.Evaluate(normal);

            depthBytes[i * 4] = (byte)(keyColor.r * 255);// R
            depthBytes[i * 4 + 1] = (byte)(keyColor.g * 255); ; // G
            depthBytes[i * 4 + 2] = (byte)(keyColor.b * 255); ; // B
            depthBytes[i * 4 + 3] = 255; // A
        }

        // Texture2D에 RGBA 데이터 적용
        resultTexture.LoadRawTextureData(depthBytes);
        resultTexture.Apply();

        //노이즈 제거
        //RemoveNoise(t2);
    }

}

[결과값]



--
*블러링된 값이 필요하면 OpenCV For Unity 사용
- Depth카메라 이미지 주변이 지글거리므로, Blur를 해줘서, 주변을 뭉개서 지글거림을 없앨 수 있다. 

using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.UnityUtils;

//노이즈 제거
    void RemoveNoise(Texture2D inputTex)
    {
        //Texture Mat으로 변환
        Mat inputMat = new Mat(inputTex.height, inputTex.width, CvType.CV_8UC4);
        Utils.texture2DToMat(inputTex, inputMat);
        Mat outputMat = new Mat();

        // 그레이스케일로 변환
        Imgproc.cvtColor(inputMat, outputMat, Imgproc.COLOR_RGBA2GRAY);

        // 노이즈 제거
        Imgproc.medianBlur(outputMat, outputMat, 3);//미디언 블러 (3 > 블러의 정도)

        //결과
        Mat reulstMat = new Mat(inputTex.height, inputTex.width, CvType.CV_8UC4);
        Imgproc.cvtColor(outputMat, reulstMat, Imgproc.COLOR_GRAY2RGB); // 그레이스케일로 변환

        Utils.matToTexture2D(reulstMat, resultTexture);
    }

 

블러한 결과값




블러를 했을떄 주변에 자글거리는게 없어진다.

 

Comments