다음을 통해 공유


HoloLens(1세대) 및 Azure 302: Computer Vision


참고 항목

Mixed Reality 아카데미 자습서는 HoloLens(1세대) 및 Mixed Reality 몰입형 헤드셋을 염두에 두고 설계되었습니다. 따라서 이러한 디바이스 개발에 대한 지침을 계속 찾고 있는 개발자를 위해 이러한 자습서를 그대로 두는 것이 중요합니다. 이러한 자습서는 HoloLens 2에 사용되는 최신 도구 집합 또는 상호 작용으로 업데이트되지 않습니다. 대신 지원되는 디바이스에서 계속 작동하도록 유지 관리됩니다. HoloLens 2용으로 개발하는 방법을 보여 주는 새로운 자습서 시리즈가 향후 게시될 예정입니다. 이 알림은 해당 자습서가 게시될 때 해당 자습서에 대한 링크로 업데이트됩니다.


이 과정에서는 혼합 현실 애플리케이션에서 Azure Computer Vision 기능을 사용하여 제공된 이미지 내에서 시각적 콘텐츠를 인식하는 방법을 알아봅니다.

인식 결과는 설명 태그로 표시됩니다. 기계 학습 모델을 학습할 필요 없이 이 서비스를 사용할 수 있습니다. 구현에 기계 학습 모델 학습이 필요한 경우 MR 및 Azure 302b를 참조하세요.

랩 결과

Microsoft Computer Vision은 클라우드의 고급 알고리즘을 사용하여 개발자에게 이미지 처리 및 분석(반환 정보 포함)을 제공하도록 설계된 API 집합입니다. 개발자는 이미지 또는 이미지 URL을 업로드하고, Microsoft Computer Vision API 알고리즘은 사용자가 선택한 입력에 따라 시각적 콘텐츠를 분석한 다음, 이미지의 유형과 품질을 식별하고, 사람의 얼굴을 감지하고(좌표를 반환) 태그를 지정하거나 이미지를 분류하는 등의 정보를 반환할 수 있습니다. 자세한 내용은 Azure Computer Vision API 페이지를 참조 하세요.

이 과정을 완료하면 다음을 수행할 수 있는 혼합 현실 HoloLens 애플리케이션이 있습니다.

  1. 탭 제스처를 사용하여 HoloLens의 카메라는 이미지를 캡처합니다.
  2. 이미지는 Azure Computer Vision API 서비스로 전송됩니다.
  3. 인식된 개체는 Unity 장면에 배치된 간단한 UI 그룹에 나열됩니다.

애플리케이션에서 결과를 디자인과 통합하는 방법은 사용자에게 달려 있습니다. 이 과정에서는 Unity 프로젝트와 Azure 서비스를 통합하는 방법을 설명합니다. 혼합 현실 애플리케이션을 향상시키기 위해이 과정에서 얻은 지식을 사용하는 것이 당신의 일입니다.

디바이스 지원

과정 HoloLens 몰입형 헤드셋
MR 및 Azure 302: Computer Vision ✔️ ✔️

참고 항목

이 과정은 주로 HoloLens에 초점을 맞추고 있지만, 이 과정에서 배운 내용을 Windows Mixed Reality 몰입형(VR) 헤드셋에 적용할 수도 있습니다. 몰입형(VR) 헤드셋에는 접근성 있는 카메라가 없으므로 PC에 연결된 외부 카메라가 필요합니다. 과정을 따라가면 몰입형(VR) 헤드셋을 지원하기 위해 사용해야 할 수 있는 변경 내용에 대한 메모가 표시됩니다.

필수 조건

참고 항목

이 자습서는 Unity 및 C#에 대한 기본 경험이 있는 개발자를 위해 설계되었습니다. 또한 이 문서의 필수 구성 요소와 서면 지침은 작성 당시 테스트 및 확인된 내용을 나타냅니다(2018년 5월). 이 과정의 정보가 아래에 나열된 것보다 최신 소프트웨어에서 찾을 수 있는 것과 완벽하게 일치한다고 가정해서는 안 되지만, 설치 도구 문서에 나열된 대로 최신 소프트웨어를 자유롭게 사용할 수 있습니다.

이 과정에는 다음 하드웨어 및 소프트웨어를 사용하는 것이 좋습니다.

시작하기 전에

  1. 이 프로젝트를 빌드하는 데 문제가 발생하지 않도록 이 자습서에서 언급한 프로젝트를 루트 또는 루트에 가까운 폴더에 만드는 것이 좋습니다(긴 폴더 경로는 빌드 시 문제를 일으킬 수 있음).
  2. HoloLens를 설정하고 테스트합니다. HoloLens 설정을 지원해야 하는 경우 HoloLens 설정 문서를 방문하세요.
  3. 새 HoloLens 앱 개발을 시작할 때 보정 및 센서 튜닝을 수행하는 것이 좋습니다(때로는 각 사용자에 대해 이러한 작업을 수행하는 데 도움이 될 수 있음).

보정에 대한 도움말은 HoloLens 보정 문서에 대한 이 링크를 따르세요.

센서 튜닝에 대한 도움말은 HoloLens 센서 튜닝 문서에 대한 이 링크를 따르세요.

1장 - Azure Portal

Azure에서 Computer Vision API 서비스를 사용하려면 애플리케이션에서 사용할 수 있도록 서비스 인스턴스를 구성해야 합니다.

  1. 먼저 Azure Portal에 로그인합니다.

    참고 항목

    Azure 계정이 아직 없는 경우 계정을 만들어야 합니다. 교실 또는 랩 상황에서 이 자습서를 따르는 경우 강사 또는 프록터 중 한 명에게 새 계정 설정에 대한 도움을 요청하세요.

  2. 로그인한 후 왼쪽 위 모서리에서 새로 만들기를 클릭하고 Computer Vision API검색하고 Enter 키를 클릭합니다.

    Azure에서 새 리소스 만들기

    참고 항목

    새 단어는 최신 포털에서 리소스 만들기로 대체되었을 수 있습니다.

  3. 새 페이지에서는 Computer Vision API 서비스에 대한 설명을 제공합니다. 이 페이지의 왼쪽 아래에서 만들기 단추를 선택하여 이 서비스와의 연결을 만듭니다.

    Computer Vision API 서비스 정보

  4. 만들기를 클릭한 후에는 다음을 수행합니다.

    1. 이 서비스 인스턴스에 원하는 이름을 삽입합니다.

    2. 구독을 선택합니다.

    3. 적절한 가격 책정 계층을 선택합니다. Computer Vision API 서비스를 처음 만드는 경우 무료 계층(F0이라는 이름)을 사용할 수 있어야 합니다.

    4. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 청구를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 랩)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹 문서를 방문하세요.

    5. 리소스 그룹의 위치를 결정합니다(새 리소스 그룹을 만드는 경우). 위치는 애플리케이션이 실행되는 지역에 있는 것이 이상적입니다. 일부 Azure 자산은 특정 지역에서만 사용할 수 있습니다.

    6. 또한 이 서비스에 적용된 사용 약관을 이해했음을 확인해야 합니다.

    7. 만들기를 클릭합니다.

      서비스 만들기 정보

  5. 만들기클릭하면 서비스가 생성될 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.

  6. 서비스 인스턴스가 만들어지면 포털에 알림이 표시됩니다.

    새 서비스에 대한 새 알림 보기

  7. 알림을 클릭하여 새 서비스 인스턴스를 탐색합니다.

    리소스로 이동 단추를 선택합니다.

  8. 알림에서 리소스 로 이동 단추를 클릭하여 새 서비스 인스턴스를 탐색합니다. 새 Computer Vision API 서비스 인스턴스로 이동합니다.

    새 Computer Vision API 서비스 이미지

  9. 이 자습서 내에서 애플리케이션은 서비스의 구독 키를 사용하여 수행되는 서비스를 호출해야 합니다.

  10. Computer Vision API 서비스의 빠른 시작 페이지에서 첫 번째 단계인 키를 잡고 키를 클릭합니다(키 아이콘으로 표시된 서비스 탐색 메뉴에 있는 파란색 하이퍼링크 키를 클릭하여 이 작업을 수행할 수도 있음). 그러면 서비스 키가 표시됩니다.

  11. 나중에 프로젝트에서 필요하므로 표시된 키 중 하나의 복사본을 가져옵니다.

  12. 빠른 시작 페이지로 돌아가서 여기에서 엔드포인트를 가져옵니다. 사용자의 지역(있는 경우 나중에 코드를 변경해야 하는 경우)에 따라 다를 수 있습니다. 나중에 사용할 이 엔드포인트의 복사본을 가져옵니다.

    새 Computer Vision API 서비스

    다양한 엔드포인트 가 여기 있는지 확인할 수 있습니다.

2장 – Unity 프로젝트 설정

다음은 혼합 현실로 개발하기 위한 일반적인 설정이며, 따라서 다른 프로젝트에 적합한 템플릿입니다.

  1. Unity를 열고 새로 만들기를 클릭합니다.

    새 Unity 프로젝트를 시작합니다.

  2. 이제 Unity 프로젝트 이름을 제공해야 합니다. MR_ComputerVision 삽입합니다. 프로젝트 형식이 3D설정되어 있는지 확인합니다. 위치를 적절한 위치로 설정합니다(루트 디렉터리에 더 가깝습니다.). 그런 다음 프로젝트 만들기를 클릭합니다.

    새 Unity 프로젝트에 대한 세부 정보를 제공합니다.

  3. Unity가 열려 있으면 기본 스크립트 편집 기가 Visual Studio로 설정되어 있는지 확인할 필요가 있습니다. 기본 설정 편집 > 으로 이동한 다음 새 창에서 외부 도구이동합니다. 외부 스크립트 편집기를 Visual Studio 2017변경합니다. 기본 설정 창을 닫습니다.

    스크립트 편집기 기본 설정을 업데이트합니다.

  4. 다음으로 파일 > 빌드 설정으로 이동하여 유니버설 Windows 플랫폼 선택한 다음 플랫폼 전환 단추를 클릭하여 선택 항목을 적용합니다.

    빌드 설정 창에서 플랫폼을 UWP로 전환합니다.

  5. 파일 > 빌드 설정에 있는 동안 다음을 확인합니다.

    1. 대상 디바이스 가 HoloLens로 설정됩니다.

      몰입형 헤드셋의 경우 대상 디바이스를 모든 디바이스설정합니다.

    2. 빌드 유형 이 D3D로 설정됨

    3. SDK 가 최신 설치됨으로 설정됨

    4. Visual Studio 버전 이 설치된 최신 버전으로 설정됨

    5. 빌드 및 실행 이 로컬 컴퓨터로 설정됩니다.

    6. 장면을 저장하고 빌드에 추가합니다.

      1. 열린 장면 추가를 선택하여 이 작업을 수행합니다. 저장 창이 나타납니다.

        열린 장면 추가 단추를 클릭합니다.

      2. 이에 대한 새 폴더 및 이후의 장면, 새 폴더 단추를 선택하여 새 폴더를 만들고 이름을 Scenes지정합니다.

        새 스크립트 폴더 만들기

      3. 새로 만든 Scenes 폴더를 연 다음 파일 이름: 텍스트 필드에 MR_ComputerVisionScene 입력한 다음 저장을 클릭합니다.

        새 장면에 이름을 지정합니다.

        Unity 프로젝트와 연결되어야 하므로 Unity 장면을 Assets 폴더 내에 저장해야 합니다. 장면 폴더(및 기타 유사한 폴더)를 만드는 것은 Unity 프로젝트를 구성하는 일반적인 방법입니다.

    7. 빌드 설정나머지 설정은 현재 기본값으로 남아 있어야 합니다.

  6. 빌드 설정 창에서 플레이어 설정 단추를 클릭하면 Inspector가 있는 공간에서 관련 패널이 열립니다.

    플레이어 설정을 엽니다.

  7. 이 패널에서 몇 가지 설정을 확인해야 합니다.

    1. 기타 설정 탭에서 다음을 수행 합니다.

      1. 런타임 버전 스크립팅은 안정적이어야 합니다(.NET 3.5 등가).

      2. 백 엔드 스크립팅은 .NET이어야 합니다.

      3. API 호환성 수준은 .NET 4.6이어야 합니다.

        다른 설정을 업데이트합니다.

    2. 게시 설정 탭의 기능 아래에서 다음을 확인합니다.

      1. InternetClient

      2. 웹캠

        게시 설정을 업데이트합니다.

    3. 패널 아래에서 XR 설정(게시 설정 아래에 있음)에서 지원되는 Virtual Reality를 확인하여 Windows Mixed Reality SDK가 추가되었는지 확인합니다.

      X R 설정을 업데이트합니다.

  8. 빌드 설정으로 돌아가면 Unity C# 프로젝트가 더 이상 회색으로 표시되지 않습니다. 이 옆에 있는 확인란을 선택합니다.

  9. 빌드 설정 창을 닫습니다.

  10. 장면 및 프로젝트 저장(FILE > SAVE SCENE / FILE > SAVE PROJECT).

3장 – 주 카메라 설정

Important

이 과정의 Unity 설정 구성 요소를 건너뛰고 코드를 계속 진행하려면 이 .unitypackage를 다운로드하고 사용자 지정 패키지로 프로젝트로 가져온 다음 5장에서 계속 진행하세요.

  1. 계층 구조 패널에서 기본 카메라를 선택합니다.

  2. 선택하면 검사기 패널에서 주 카메라모든 구성 요소를 볼 수 있습니다.

    1. 카메라 개체이름은 주 카메라여야 합니다(맞춤법 유의하세요!)

    2. Main Camera 태그는 MainCamera설정해야 합니다(맞춤법 유의하세요!)

    3. 변환 위치0, 0, 0으로 설정되어 있는지 확인합니다.

    4. 플래그 지우기를 단색으로 설정합니다(몰입형 헤드셋의 경우 무시).

    5. 카메라 구성 요소의 배경색을 검은색, 알파 0(16진수 코드: #00000000)으로 설정합니다(몰입형 헤드셋의 경우 무시).

      카메라 구성 요소를 업데이트합니다.

  3. 다음으로, 주 카메라에 연결된 간단한 "Cursor" 개체를 만들어야 합니다. 그러면 애플리케이션이 실행될 때 이미지 분석 출력을 배치하는 데 도움이 됩니다. 이 커서는 카메라 포커스의 중심점을 결정합니다.

커서를 만들려면 다음을 수행합니다.

  1. 계층 패널에서 주 카메라를 마우스 오른쪽 단추로 클릭합니다. 3D 개체 아래에서 구를 클릭합니다.

    커서 개체를 선택합니다.

  2. Sphere 이름을 커서바꾸고(커서 개체를 두 번 클릭하거나 개체가 선택된 'F2' 키보드 단추를 누름) 기본 카메라식으로 있는지 확인합니다.

  3. 계층 패널에서 커서를 마우스 왼쪽 단추로 클릭합니다. 커서를 선택한 상태에서 검사기 패널에서 다음 변수를 조정합니다.

    1. 변환 위치를 0, 0, 5로 설정

    2. 배율을 0.02, 0.02, 0.02로 설정합니다.

      변환 위치 및 배율을 업데이트합니다.

4장 - 레이블 시스템 설정

HoloLens의 카메라로 이미지를 캡처하면 해당 이미지가 분석을 위해 Azure Computer Vision API Service 인스턴스로 전송됩니다.

해당 분석 결과는 Tags라는 인식된 개체의 목록이 됩니다.

레이블(세계 공간의 3D 텍스트)을 사용하여 사진을 찍은 위치에 이러한 태그를 표시합니다.

다음 단계에서는 Label 개체를 설정하는 방법을 보여줍니다.

  1. 계층 패널의 아무 곳이나 마우스 오른쪽 단추로 클릭하고(이 시점에서 위치는 중요하지 않음) 3D 개체 아래에서 3D 텍스트를 추가합니다. LabelText 이름을 지정합니다.

    3D Text 개체를 만듭니다.

  2. 계층 패널에서 LabelText를 마우스 왼쪽 단추로 클릭합니다. LabelText선택한 상태에서 검사기 패널에서 다음 변수를 조정합니다.

    1. 위치를 0,0,0으로 설정
    2. 배율을 0.01, 0.01, 0.01로 설정합니다.
    3. 구성 요소 에서 텍스트 메시:
    4. 텍스트 내의 모든 텍스트를 "..."로 바꿉니다.
    5. 앵커가운데 가운데로 설정
    6. 맞춤을 가운데로 설정
    7. 탭 크기를 4로 설정
    8. 글꼴 크기를 50으로 설정
    9. #FFFFFFFF 설정

    텍스트 구성 요소

  3. [계층 구조] 패널에서 [프로젝트 패널] 내의 [자산 폴더]로 LabelText끕니다. 이렇게 하면 LabelTextPrefab으로 만들어 코드에서 인스턴스화할 수 있습니다.

    LabelText 개체의 프리팹을 만듭니다.

  4. 계층 패널에서 LabelText삭제해야 여는 장면에 표시되지 않습니다. 이제 Assets 폴더에서 개별 인스턴스를 호출하는 프리팹이므로 장면 내에 유지할 필요가 없습니다.

  5. 계층 패널의 최종 개체 구조는 아래 이미지에 표시된 것과 같아야 합니다.

    계층 패널의 최종 구조입니다.

5장 – ResultsLabel 클래스 만들기

만들어야 하는 첫 번째 스크립트는 다음을 담당하는 ResultsLabel 클래스입니다.

  • 카메라의 위치를 기준으로 적절한 월드 공간에서 레이블을 만듭니다.
  • 이미지 Anaysis의 태그 표시

이 클래스를 만들려면 다음을 수행합니다.

  1. 프로젝트 패널을 마우스 오른쪽 단추로 클릭한 다음 폴더를 만듭니 > 다. 폴더 이름을 스크립트로 지정합니다.

    스크립트 폴더를 만듭니다.

  2. Scripts 폴더를 만들면 두 번 클릭하여 엽니다. 그런 다음 해당 폴더 내에서 마우스 오른쪽 단추를 클릭하고 C# 스크립트 만들기 >선택합니다. 스크립트 이름을 ResultsLabel로 지정합니다.

  3. ResultsLabel 스크립트를 두 번 클릭하여 Visual Studio에서 엽니다.

  4. 클래스 내부에 ResultsLabel 클래스에 다음 코드를 삽입합니다.

        using System.Collections.Generic;
        using UnityEngine;
    
        public class ResultsLabel : MonoBehaviour
        {	
            public static ResultsLabel instance;
    
            public GameObject cursor;
    
            public Transform labelPrefab;
    
            [HideInInspector]
            public Transform lastLabelPlaced;
    
            [HideInInspector]
            public TextMesh lastLabelPlacedText;
    
            private void Awake()
            {
                // allows this instance to behave like a singleton
                instance = this;
            }
    
            /// <summary>
            /// Instantiate a Label in the appropriate location relative to the Main Camera.
            /// </summary>
            public void CreateLabel()
            {
                lastLabelPlaced = Instantiate(labelPrefab, cursor.transform.position, transform.rotation);
    
                lastLabelPlacedText = lastLabelPlaced.GetComponent<TextMesh>();
    
                // Change the text of the label to show that has been placed
                // The final text will be set at a later stage
                lastLabelPlacedText.text = "Analysing...";
            }
    
            /// <summary>
            /// Set the Tags as Text of the last Label created. 
            /// </summary>
            public void SetTagsToLastLabel(Dictionary<string, float> tagsDictionary)
            {
                lastLabelPlacedText = lastLabelPlaced.GetComponent<TextMesh>();
    
                // At this point we go through all the tags received and set them as text of the label
                lastLabelPlacedText.text = "I see: \n";
    
                foreach (KeyValuePair<string, float> tag in tagsDictionary)
                {
                    lastLabelPlacedText.text += tag.Key + ", Confidence: " + tag.Value.ToString("0.00 \n");
                }    
            }
        }
    
  5. Unity로 돌아가기 전에 Visual Studio에서 변경 내용을 저장해야 합니다.

  6. Unity 편집기로 돌아가서 Scripts 폴더의 ResultsLabel 클래스를 클릭하고 계층 패널의 주 카메라 개체로 끕니다.

  7. 주 카메라를 클릭하고 검사기 패널확인합니다.

방금 카메라로 끌어 온 스크립트에는 커서레이블 프리팹이라는 두 개의 필드가 있습니다.

  1. 아래 이미지와 같이 Cursor라는 개체를 계층 패널에서 커서라는 슬롯으로 끕니다.

  2. 아래 이미지와 같이 LabelText라는 개체를 프로젝트 패널자산 폴더에서 레이블 프리팹이라는 슬롯으로 끕니다.

    Unity 내에서 참조 대상을 설정합니다.

6장 – ImageCapture 클래스 만들기

만들려는 다음 클래스는 ImageCapture 클래스입니다. 이 클래스는 다음을 담당합니다.

  • HoloLens 카메라를 사용하여 이미지를 캡처하고 앱 폴더에 저장합니다.
  • 사용자로부터 탭 제스처 캡처

이 클래스를 만들려면 다음을 수행합니다.

  1. 이전에 만든 Scripts 폴더로 이동합니다.

  2. 폴더 내부를 마우스 오른쪽 단추로 클릭하고 C# 스크립트를 만듭니 > 다. ImageCapture 스크립트 를 호출합니다.

  3. ImageCapture 스크립트를 두 번 클릭하여 Visual Studio에서 엽니다.

  4. 다음 네임스페이스를 파일 맨 위에 추가합니다.

        using System.IO;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
        using UnityEngine.XR.WSA.WebCam;
    
  5. 그런 다음, Start() 메서드 위에 ImageCapture 클래스 내에 다음 변수를 추가합니다.

        public static ImageCapture instance; 
        public int tapsCount;
        private PhotoCapture photoCaptureObject = null;
        private GestureRecognizer recognizer;
        private bool currentlyCapturing = false;
    

tapsCount 변수는 사용자로부터 캡처된 탭 제스처의 수를 저장합니다. 이 숫자는 캡처된 이미지의 이름 지정에 사용됩니다.

  1. 이제 Awake()Start() 메서드에 대한 코드를 추가해야 합니다. 클래스가 초기화될 때 호출됩니다.

        private void Awake()
        {
            // Allows this instance to behave like a singleton
            instance = this;
        }
    
        void Start()
        {
            // subscribing to the HoloLens API gesture recognizer to track user gestures
            recognizer = new GestureRecognizer();
            recognizer.SetRecognizableGestures(GestureSettings.Tap);
            recognizer.Tapped += TapHandler;
            recognizer.StartCapturingGestures();
        }
    
  2. 탭 제스처가 발생할 때 호출되는 처리기를 구현합니다.

        /// <summary>
        /// Respond to Tap Input.
        /// </summary>
        private void TapHandler(TappedEventArgs obj)
        {
            // Only allow capturing, if not currently processing a request.
            if(currentlyCapturing == false)
            {
                currentlyCapturing = true;
    
                // increment taps count, used to name images when saving
                tapsCount++;
    
                // Create a label in world space using the ResultsLabel class
                ResultsLabel.instance.CreateLabel();
    
                // Begins the image capture and analysis procedure
                ExecuteImageCaptureAndAnalysis();
            }
        }
    

TapHandler() 메서드는 사용자로부터 캡처된 탭 수를 증가시키고 현재 커서 위치를 사용하여 새 레이블의 위치를 결정합니다.

그런 다음 이 메서드는 ExecuteImageCaptureAndAnalysis() 메서드를 호출하여 이 애플리케이션의 핵심 기능을 시작합니다.

  1. 이미지가 캡처되고 저장되면 다음 처리기가 호출됩니다. 프로세스가 성공하면 결과를 분석을 위해 VisionManager (아직 만들지 않은)에 전달됩니다.

        /// <summary>
        /// Register the full execution of the Photo Capture. If successful, it will begin 
        /// the Image Analysis process.
        /// </summary>
        void OnCapturedPhotoToDisk(PhotoCapture.PhotoCaptureResult result)
        {
            // Call StopPhotoMode once the image has successfully captured
            photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
        }
    
        void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
        {
            // Dispose from the object in memory and request the image analysis 
            // to the VisionManager class
            photoCaptureObject.Dispose();
            photoCaptureObject = null;
            StartCoroutine(VisionManager.instance.AnalyseLastImageCaptured()); 
        }
    
  2. 그런 다음 애플리케이션에서 이미지 캡처 프로세스를 시작하고 이미지를 저장하는 데 사용하는 메서드를 추가합니다.

        /// <summary>    
        /// Begin process of Image Capturing and send To Azure     
        /// Computer Vision service.   
        /// </summary>    
        private void ExecuteImageCaptureAndAnalysis()  
        {    
            // Set the camera resolution to be the highest possible    
            Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();    
    
            Texture2D targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
    
            // Begin capture process, set the image format    
            PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)    
            {    
                photoCaptureObject = captureObject;    
                CameraParameters camParameters = new CameraParameters();    
                camParameters.hologramOpacity = 0.0f;    
                camParameters.cameraResolutionWidth = targetTexture.width;    
                camParameters.cameraResolutionHeight = targetTexture.height;    
                camParameters.pixelFormat = CapturePixelFormat.BGRA32;
    
                // Capture the image from the camera and save it in the App internal folder    
                captureObject.StartPhotoModeAsync(camParameters, delegate (PhotoCapture.PhotoCaptureResult result)
                {    
                    string filename = string.Format(@"CapturedImage{0}.jpg", tapsCount);
    
                    string filePath = Path.Combine(Application.persistentDataPath, filename);
    
                    VisionManager.instance.imagePath = filePath;
    
                    photoCaptureObject.TakePhotoAsync(filePath, PhotoCaptureFileOutputFormat.JPG, OnCapturedPhotoToDisk);
    
                    currentlyCapturing = false;
                });   
            });    
        }
    

Warning

이때 Unity 편집기 콘솔 패널오류가 표시됩니다. 코드가 다음 챕터에서 만들 VisionManager 클래스를 참조하기 때문입니다.

7장 - Azure 및 이미지 분석 호출

만들어야 하는 마지막 스크립트는 VisionManager 클래스입니다.

이 클래스는 다음을 담당합니다.

  • 바이트 배열로 캡처된 최신 이미지를 로드합니다.
  • 분석을 위해 Azure Computer Vision API Service 인스턴스로 바이트 배열을 보냅니다.
  • 응답을 JSON 문자열로 수신합니다.
  • 응답을 역직렬화하고 결과 태그를 ResultsLabel 클래스에 전달합니다.

이 클래스를 만들려면 다음을 수행합니다.

  1. 스크립트 폴더를 두 번 클릭하여 엽니다.

  2. 스크립트 폴더 내부를 마우스 오른쪽 단추로 클릭하고 C# 스크립트 만들기 > 를 클릭합니다. 스크립트 이름을 VisionManager로 지정합니다.

  3. 새 스크립트를 두 번 클릭하여 Visual Studio에서 엽니다.

  4. VisionManager 클래스의 맨 위에 있는 네임스페이스를 다음과 동일하게 업데이트합니다.

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. 스크립트 맨 위에 있는 VisionManager 클래스(Start() 메서드 위)에서 이제 Azure에서 역직렬화된 JSON 응답을 나타내는 두 개의 클래스를 만들어야 합니다.

        [System.Serializable]
        public class TagData
        {
            public string name;
            public float confidence;
        }
    
        [System.Serializable]
        public class AnalysedObject
        {
            public TagData[] tags;
            public string requestId;
            public object metadata;
        }
    

    참고 항목

    Unity 라이브러리를 사용하여 역직렬화할 수 있도록 선언 전에 TagDataAnalysiedObject 클래스에 [System.Serializable] 특성이 추가되어야 합니다.

  6. VisionManager 클래스에서 다음 변수를 추가해야 합니다.

        public static VisionManager instance;
    
        // you must insert your service key here!    
        private string authorizationKey = "- Insert your key here -";    
        private const string ocpApimSubscriptionKeyHeader = "Ocp-Apim-Subscription-Key";
        private string visionAnalysisEndpoint = "https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags";   // This is where you need to update your endpoint, if you set your location to something other than west-us.
    
        internal byte[] imageBytes;
    
        internal string imagePath;
    

    Warning

    authorizationKey 변수에 인증 키를 삽입해야 합니다. 이 과정의 시작 부분인 1장에서 인증 키를 적어 두었을 것입니다.

    Warning

    visionAnalysisEndpoint 변수는 이 예제에 지정된 변수와 다를 수 있습니다. 서부는 미국 서부 지역에 대해 만들어진 서비스 인스턴스를 엄격하게 나타냅니다. 엔드포인트 URL로 업데이트합니다. 다음과 같은 몇 가지 예가 있습니다.

    • 서유럽: https://westeurope.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • 동남아시아: https://southeastasia.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
    • 오스트레일리아 동부: https://australiaeast.api.cognitive.microsoft.com/vision/v1.0/analyze?visualFeatures=Tags
  7. 이제 깨어에 대한 코드를 추가해야 합니다.

        private void Awake()
        {
            // allows this instance to behave like a singleton
            instance = this;
        }
    
  8. 다음으로, 아래 정적 스트림 메서드를 사용하여 코루틴을 추가하여 ImageCapture 클래스에서 캡처한 이미지 분석 결과를 가져옵니다.

        /// <summary>
        /// Call the Computer Vision Service to submit the image.
        /// </summary>
        public IEnumerator AnalyseLastImageCaptured()
        {
            WWWForm webForm = new WWWForm();
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Post(visionAnalysisEndpoint, webForm))
            {
                // gets a byte array out of the saved image
                imageBytes = GetImageAsByteArray(imagePath);
                unityWebRequest.SetRequestHeader("Content-Type", "application/octet-stream");
                unityWebRequest.SetRequestHeader(ocpApimSubscriptionKeyHeader, authorizationKey);
    
                // the download handler will help receiving the analysis from Azure
                unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
    
                // the upload handler will help uploading the byte array with the request
                unityWebRequest.uploadHandler = new UploadHandlerRaw(imageBytes);
                unityWebRequest.uploadHandler.contentType = "application/octet-stream";
    
                yield return unityWebRequest.SendWebRequest();
    
                long responseCode = unityWebRequest.responseCode;     
    
                try
                {
                    string jsonResponse = null;
                    jsonResponse = unityWebRequest.downloadHandler.text;
    
                    // The response will be in Json format
                    // therefore it needs to be deserialized into the classes AnalysedObject and TagData
                    AnalysedObject analysedObject = new AnalysedObject();
                    analysedObject = JsonUtility.FromJson<AnalysedObject>(jsonResponse);
    
                    if (analysedObject.tags == null)
                    {
                        Debug.Log("analysedObject.tagData is null");
                    }
                    else
                    {
                        Dictionary<string, float> tagsDictionary = new Dictionary<string, float>();
    
                        foreach (TagData td in analysedObject.tags)
                        {
                            TagData tag = td as TagData;
                            tagsDictionary.Add(tag.name, tag.confidence);                            
                        }
    
                        ResultsLabel.instance.SetTagsToLastLabel(tagsDictionary);
                    }
                }
                catch (Exception exception)
                {
                    Debug.Log("Json exception.Message: " + exception.Message);
                }
    
                yield return null;
            }
        }
    
        /// <summary>
        /// Returns the contents of the specified file as a byte array.
        /// </summary>
        private static byte[] GetImageAsByteArray(string imageFilePath)
        {
            FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream);
            return binaryReader.ReadBytes((int)fileStream.Length);
        }  
    
  9. Unity로 돌아가기 전에 Visual Studio에서 변경 내용을 저장해야 합니다.

  10. Unity 편집기로 돌아가서 Scripts 폴더의 VisionManagerImageCapture 클래스를 클릭하고 계층 구조 패널Main Camera 개체로 끕니다.

8장 – 빌드 전

애플리케이션에 대한 철저한 테스트를 수행하려면 HoloLens에 테스트용으로 로드해야 합니다. 이렇게 하기 전에 다음을 확인합니다.

  • 2장에 언급된 모든 설정이 올바르게 설정됩니다.
  • 모든 스크립트는 Main Camera 개체에 연결됩니다.
  • 주 카메라 검사기 패널모든 필드가 제대로 할당됩니다.
  • authorizationKey 변수에 인증 키를 삽입해야 합니다.
  • 또한 VisionManager 스크립트에서 엔드포인트를 확인하고 해당 지역에 맞춰야 합니다(이 문서에서는 기본적으로 west-us를 사용).

9장 - UWP 솔루션 빌드 및 애플리케이션 테스트용 로드

이제 이 프로젝트의 Unity 섹션에 필요한 모든 항목이 완료되었으므로 Unity에서 빌드해야 합니다.

  1. 빌드 설정 - 파일 > 빌드 설정으로 이동합니다...

  2. 빌드 설정 창에서 빌드를 클릭합니다.

    Unity에서 앱 빌드

  3. 아직 없는 경우 Unity C# 프로젝트를 선택합니다.

  4. 빌드를 클릭한 다음 Unity에서 파일 탐색기 창이 시작됩니다. 여기서는 앱을 만들 폴더를 선택합니다. 이제 해당 폴더를 만들고 이름을 앱으로 지정합니다. 그런 다음 앱 폴더를 선택한 상태에서 폴더 선택 키를 누릅니 다.

  5. Unity는 App 폴더에 프로젝트 빌드를 시작합니다.

  6. Unity가 빌드를 마치면(시간이 좀 걸릴 수 있음) 빌드 위치에서 파일 탐색기 창이 열립니다(작업 표시줄이 항상 창 위에 표시되지는 않지만 새 창이 추가되었음을 알려 주시기 때문에 작업 표시줄 확인).

10장 – HoloLens에 배포

HoloLens에 배포하려면:

  1. HoloLens의 IP 주소(원격 배포용)가 필요하며 HoloLens가 개발자 모드있는지 확인합니다. 방법:

    1. HoloLens를 착용하는 동안 설정을 엽니다.
    2. 네트워크 및 인터넷 > Wi-Fi > 고급 옵션으로 이동
    3. IPv4 주소를 확인합니다.
    4. 다음으로, 설정으로 다시 이동한 다음 개발자용 업데이트 및 보안 > 으로 이동합니다.
    5. 개발자 모드를 설정합니다.
  2. 새 Unity 빌드( 폴더)로 이동하고 Visual Studio를 사용하여 솔루션 파일을 엽니다.

  3. 솔루션 구성에서 디버그를 선택합니다.

  4. 솔루션 플랫폼에서 x86, 원격 머신을 선택합니다.

    Visual Studio에서 솔루션을 배포합니다.

  5. 빌드 메뉴로 이동하여 솔루션 배포를 클릭하여 HoloLens에 애플리케이션을 테스트용으로 로드합니다.

  6. 이제 시작 준비가 된 HoloLens의 설치된 앱 목록에 앱이 표시됩니다.

참고 항목

몰입형 헤드셋에 배포하려면 솔루션 플랫폼을 로컬 머신으로 설정하고 x86을 플랫폼으로 사용하여 구성디버그설정합니다. 그런 다음 빌드 메뉴를 사용하여 로컬 컴퓨터에 배포하고 솔루션 배포를 선택합니다.

완성된 Computer Vision API 애플리케이션

축하합니다. Azure Computer Vision API를 활용하여 실제 개체를 인식하고 표시된 내용에 대한 신뢰를 표시하는 혼합 현실 앱을 빌드했습니다.

랩 결과

보너스 연습

연습 1

Tags 매개 변수를 사용한 것처럼(VisionManager 내에서 사용되는 엔드포인트 내에서 입증된 대로) 앱을 확장하여 다른 정보를 검색합니다. HERE에 액세스할 수 있는 다른 매개 변수를 살펴봅니다.

연습 2

반환된 Azure 데이터를 더 대화적이고 읽기 쉬운 방식으로 표시하여 숫자를 숨길 수 있습니다. 봇이 사용자에게 말하는 것처럼.