Computer Vision JavaScript 퀵 스타트

등록일시: 2017-11-16 08:00,  수정일시: 2017-11-09 05:31
조회수: 3,958
이 문서는 Cognitive Services 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.
본문에서는 JavaScript를 사용해서 Computer Vision API를 사용하는 방법을 살펴봅니다.

본문에서는 JavaScript와 Computer Vision API를 사용해서 다음과 같은 작업을 신속하게 수행하기 위해 필요한 유용한 정보와 예제 코드를 제공합니다:

무료 구독 키를 발급받는 방법은 Computer Vision API 구독 키 발급받기 문서를 참고하시기 바랍니다.

본문의 예제들 대부분은 jQuery 1.9.0 버전을 사용하고 있습니다. jQuery를 사용하지 않고 순수한 JavaScript만 사용하는 예제는 지능적으로 썸네일 이미지 생성하기 절의 예제를 참고하시기 바랍니다.

JavaScript를 이용해서 Computer Vision API로 이미지 분석하기

이미지 분석 메서드를 사용하면 이미지 내용에 기반한 시각적 특징들을 추출해낼 수 있습니다. 이미지를 업로드하거나 이미지의 URL을 지정하고, 다음 중 어떤 시각적 특징을 반환할지 선택하면 됩니다:

  • 86 가지 범주 분류에 정의된 범주
  • 이미지 내용에 관한 태그들의 상세한 목록
  • 이미지 내용에 관한 완전한 문장으로 구성된 설명
  • 이미지에 포함된 얼굴의 좌표, 성별 및 나이
  • 이미지 유형 (클립아트 또는 선 그리기)
  • 지배적 색상, 강조색 또는 이미지의 흑백 여부
  • 이미지에 포르노 또는 음란물이 포함되어 있는지 여부

이미지 분석 JavaScript 요청 예제

예제를 실행하려면 다음의 과정을 따라하십시오:

  1. analyze.html 등의 이름으로 파일을 생성하고, 다음 예제 코드를 복사하여 붙여 넣은 다음 저장합니다.
  2. subscriptionKey의 값을 여러분이 발급받은 유효한 구독 키로 변경합니다.
  3. uriBase의 값을 구독 키를 발급받은 지역의 URL 주소로 변경합니다.
  4. 파일을 브라우저에 드래그 & 드랍합니다.
  5. Analyze image 버튼을 클릭합니다.
<!DOCTYPE html>
<html>
<head>
    <title>Analyze Sample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    function processImage() {
        // **********************************************
        // *** Update or verify the following values. ***
        // **********************************************

        // Replace the subscriptionKey string value with your valid subscription key.
        var subscriptionKey = "13hc77781f7e4b19b5fcdd72a8df7156";

        // Replace or verify the region.
        //
        // You must use the same region in your REST API call as you used to obtain your subscription keys.
        // For example, if you obtained your subscription keys from the westus region, replace
        // "westcentralus" in the URI below with "westus".
        //
        // NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
        // a free trial subscription key, you should not need to change this region.
        var uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/analyze";

        // Request parameters.
        var params = {
            "visualFeatures": "Categories,Description,Color",
            "details": "",
            "language": "en",
        };

        // Display the image.
        var sourceImageUrl = document.getElementById("inputImage").value;
        document.querySelector("#sourceImage").src = sourceImageUrl;

        // Perform the REST API call.
        $.ajax({
            url: uriBase + "?" + $.param(params),

            // Request headers.
            beforeSend: function(xhrObj){
                xhrObj.setRequestHeader("Content-Type","application/json");
                xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
            },

            type: "POST",

            // Request body.
            data: '{"url": ' + '"' + sourceImageUrl + '"}',
        })

        .done(function(data) {
            // Show formatted JSON on webpage.
            $("#responseTextArea").val(JSON.stringify(data, null, 2));
        })

        .fail(function(jqXHR, textStatus, errorThrown) {
            // Display error message.
            var errorString = (errorThrown === "") ? "Error. " : errorThrown + " (" + jqXHR.status + "): ";
            errorString += (jqXHR.responseText === "") ? "" : jQuery.parseJSON(jqXHR.responseText).message;
            alert(errorString);
        });
    };
</script>

<h1>Analyze image:</h1>
Enter the URL to an image of a natural or artificial landmark, then click the <strong>Analyze image</strong> button.
<br><br>
Image to analyze: <input type="text" name="inputImage" id="inputImage" value="http://upload.wikimedia.org/wikipedia/commons/3/3c/Shaki_waterfall.jpg" />
<button onclick="processImage()">Analyze image</button>
<br><br>
<div id="wrapper" style="width:1020px; display:table;">
    <div id="jsonOutput" style="width:600px; display:table-cell;">
        Response:
        <br><br>
        <textarea id="responseTextArea" class="UIInput" style="width:580px; height:400px;"></textarea>
    </div>
    <div id="imageDiv" style="width:420px; display:table-cell;">
        Source image:
        <br><br>
        <img id="sourceImage" width="400" />
    </div>
</div>
</body>
</html>

이미지 분석 결과 응답 살펴보기

정상적으로 처리된 응답은 JSON 형식으로 반환됩니다. 다음은 성공한 응답의 사례입니다:

{
  "categories": [
    {
      "name": "outdoor_water",
      "score": 0.9921875
    }
  ],
  "description": {
    "tags": [
      "nature",
      "water",
      "waterfall",
      "outdoor",
      "rock",
      "mountain",
      "rocky",
      "grass",
      "hill",
      "top",
      "covered",
      "hillside",
      "standing",
      "side",
      "group",
      "walking",
      "white",
      "man",
      "large",
      "snow",
      "grazing",
      "forest",
      "slope",
      "herd",
      "river",
      "giraffe",
      "field"
    ],
    "captions": [
      {
        "text": "a large waterfall over a rocky cliff",
        "confidence": 0.9165146827843689
      }
    ]
  },
  "requestId": "63d3c630-7f3d-43d7-8a97-143012fc53f4",
  "metadata": {
    "width": 1280,
    "height": 959,
    "format": "Jpeg"
  },
  "color": {
    "dominantColorForeground": "Grey",
    "dominantColorBackground": "Green",
    "dominantColors": [
      "Grey",
      "Green"
    ],
    "accentColor": "4D5E2F",
    "isBWImg": false
  }
}

도메인 특정 모델 사용하기

도메인 특정 (Domain-Specific) 모델은 이미지에 존재하는 특정 개체의 모음을 식별하도록 특별히 훈련된 모델입니다. 현재 사용할 수 있는 도메인 특정 모델은 두 가지로, 유명인사 모델과 랜드마크 모델이 그것입니다. 다음 예제는 이미지에서 랜드마크를 식별합니다.

랜드마크 JavaScript 요청 예제

예제를 실행하려면 다음의 과정을 따라하십시오:

  1. landmark.html 등의 이름으로 파일을 생성하고, 다음 예제 코드를 복사하여 붙여 넣은 다음 저장합니다.
  2. subscriptionKey의 값을 여러분이 발급받은 유효한 구독 키로 변경합니다.
  3. uriBase의 값을 구독 키를 발급받은 지역의 URL 주소로 변경합니다.
  4. 파일을 브라우저에 드래그 & 드랍합니다.
  5. Analyze image 버튼을 클릭합니다.
<!DOCTYPE html>
<html>
<head>
    <title>Landmark Sample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    function processImage() {
        // **********************************************
        // *** Update or verify the following values. ***
        // **********************************************

        // Replace the subscriptionKey string value with your valid subscription key.
        var subscriptionKey = "13hc77781f7e4b19b5fcdd72a8df7156";

        // Replace or verify the region.
        //
        // You must use the same region in your REST API call as you used to obtain your subscription keys.
        // For example, if you obtained your subscription keys from the westus region, replace
        // "westcentralus" in the URI below with "westus".
        //
        // NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
        // a free trial subscription key, you should not need to change this region.
        //
        // Also, if you want to use the celebrities model, change "landmarks" to "celebrities" here and in
        // uriBuilder.setParameter to use the Celebrities model.
        var uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/models/landmarks/analyze";

        // Request parameters.
        var params = {
            "model": "landmarks", // Use "model": "celebrities" to use the Celebrities model.
        };

        // Display the image.
        var sourceImageUrl = document.getElementById("inputImage").value;
        document.querySelector("#sourceImage").src = sourceImageUrl;

        // Perform the REST API call.
        $.ajax({
            url: uriBase + "?" + $.param(params),

            // Request headers.
            beforeSend: function(xhrObj) {
                xhrObj.setRequestHeader("Content-Type", "application/json");
                xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
            },

            type: "POST",

            // Request body.
            data: '{"url": ' + '"' + sourceImageUrl + '"}',
        })

        .done(function(data) {
            // Show formatted JSON on webpage.
            $("#responseTextArea").val(JSON.stringify(data, null, 2));
        })

        .fail(function(jqXHR, textStatus, errorThrown) {
            // Display error message.
            var errorString = (errorThrown === "") ? "Error. " : errorThrown + " (" + jqXHR.status + "): ";
            errorString += (jqXHR.responseText === "") ? "" : jQuery.parseJSON(jqXHR.responseText).message;
            alert(errorString);
        });
    };
</script>

<h1>Landmark image:</h1>
Enter the URL to an image of a natural or artificial landmark, then click the <strong>Analyze image</strong> button.
<br><br>
Landscape image to analyze: <input type="text" name="inputImage" id="inputImage" value="https://upload.wikimedia.org/wikipedia/commons/2/23/Space_Needle_2011-07-04.jpg" />
<button onclick="processImage()">Analyze image</button>
<br><br>
<div id="wrapper" style="width:1020px; display:table;">
    <div id="jsonOutput" style="width:600px; display:table-cell;">
        Response:
        <br><br>
        <textarea id="responseTextArea" class="UIInput" style="width:580px; height:400px;"></textarea>
    </div>
    <div id="imageDiv" style="width:420px; display:table-cell;">
        Source image:
        <br><br>
        <img id="sourceImage" width="400" />
    </div>
</div>
</body>
</html>

랜드마크 응답 예제 살펴보기

정상적으로 처리된 응답은 JSON 형식으로 반환됩니다. 다음은 성공한 응답의 사례입니다:

{
  "requestId": "fe0d4539-7a21-4fc6-b7af-3bb24beba390",
  "metadata": {
    "width": 2096,
    "height": 4132,
    "format": "Jpeg"
  },
  "result": {
    "landmarks": [
      {
        "name": "Space Needle",
        "confidence": 0.9998178
      }
    ]
  }
}

JavaScript를 이용해서 Computer Vision API로 썸네일 이미지 생성하기

썸네일 생성 메서드를 사용하면 이미지의 관심 영역(ROI)을 중심으로 원하는 높이와 너비로 이미지를 자르고, 원본 이미지와 종횡비가 다른 썸네일을 생성할 수도 있습니다.

썸네일 이미지 생성하기 JavaScript 요청 예제

예제를 실행하려면 다음의 과정을 따라하십시오:

  1. thumbnail.html 등의 이름으로 파일을 생성하고, 다음 예제 코드를 복사하여 붙여 넣은 다음 저장합니다.
  2. subscriptionKey의 값을 여러분이 발급받은 유효한 구독 키로 변경합니다.
  3. uriBase의 값을 구독 키를 발급받은 지역의 URL 주소로 변경합니다.
  4. 파일을 브라우저에 드래그 & 드랍합니다.
  5. Generate thumbnail 버튼을 클릭합니다.
<!DOCTYPE html>
<html>
<head>
    <title>Thumbnail Sample</title>
</head>
<body>

<script type="text/javascript">
    function processImage() {
        // **********************************************
        // *** Update or verify the following values. ***
        // **********************************************

        // Replace the subscriptionKey string value with your valid subscription key.
        var subscriptionKey = "13hc77781f7e4b19b5fcdd72a8df7156";

        // Replace or verify the region.
        //
        // You must use the same region in your REST API call as you used to obtain your subscription keys.
        // For example, if you obtained your subscription keys from the westus region, replace
        // "westcentralus" in the URI below with "westus".
        //
        // NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
        // a free trial subscription key, you should not need to change this region.
        var uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/generateThumbnail";

        // Request parameters.
        var params = "?width=100&height=150&smartCropping=true";

        // Display the source image.
        var sourceImageUrl = document.getElementById("inputImage").value;
        document.querySelector("#sourceImage").src = sourceImageUrl;

        // Prepare the REST API call:

        // Create the HTTP Request object.
        var xhr = new XMLHttpRequest();

        // Identify the request as a POST, with the URL and parameters.
        xhr.open("POST", uriBase + params);

        // Add the request headers.
        xhr.setRequestHeader("Content-Type","application/json");
        xhr.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);

        // Set the response type to "blob" for the thumbnail image data.
        xhr.responseType = "blob";

        // Process the result of the REST API call.
        xhr.onreadystatechange = function(e) {
            if(xhr.readyState === XMLHttpRequest.DONE) {

                // Thumbnail successfully created.
                if (xhr.status === 200) {
                    // Show response headers.
                    var s = JSON.stringify(xhr.getAllResponseHeaders(), null, 2);
                    document.getElementById("responseTextArea").value = JSON.stringify(xhr.getAllResponseHeaders(), null, 2);

                    // Show thumbnail image.
                    var urlCreator = window.URL || window.webkitURL;
                    var imageUrl = urlCreator.createObjectURL(this.response);
                    document.querySelector("#thumbnailImage").src = imageUrl;
                } else {
                    // Display the error message. The error message is the response body as a JSON string. 
                    // The code in this code block extracts the JSON string from the blob response.
                    var reader = new FileReader();

                    // This event fires after the blob has been read.
                    reader.addEventListener('loadend', (e) => {
                        document.getElementById("responseTextArea").value = JSON.stringify(JSON.parse(e.srcElement.result), null, 2);
                    });

                    // Start reading the blob as text.
                    reader.readAsText(xhr.response);
                }
            }
        }

        // Execute the REST API call.
        xhr.send('{"url": ' + '"' + sourceImageUrl + '"}');
    };
</script>

<h1>Generate thumbnail image:</h1>
Enter the URL to an image to use in creating a thumbnail image, then click the <strong>Generate thumbnail</strong> button.
<br><br>
Image for thumnail: <input type="text" name="inputImage" id="inputImage" value="https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Shorkie_Poo_Puppy.jpg/1280px-Shorkie_Poo_Puppy.jpg" />
<button onclick="processImage()">Generate thumbnail</button>
<br><br>
<div id="wrapper" style="width:1160px; display:table;">
    <div id="jsonOutput" style="width:600px; display:table-cell;">
        Response:
        <br><br>
        <textarea id="responseTextArea" class="UIInput" style="width:580px; height:400px;"></textarea>
    </div>
    <div id="imageDiv" style="width:420px; display:table-cell;">
        Source image:
        <br><br>
        <img id="sourceImage" width="400" />
    </div>
    <div id="thumbnailDiv" style="width:140px; display:table-cell;">
        Thumbnail:
        <br><br>
        <img id="thumbnailImage" />
    </div>
</div>
</body>
</html>

썸네일 응답 가져오기

정상적으로 성공한 응답에는 썸네일 이미지의 이진 데이터가 담겨서 반환됩니다. 반면 요청이 실패한 경우에는 오류 코드와 잘못된 사항을 확인하는데 도움이 되는 메시지가 응답에 포함됩니다.

JavaScript와 Computer Vision API를 이용한 광학 문자 인식 (OCR)

광학 문자 인식 (OCR) 메서드를 사용하면 이미지에 포함된 텍스트를 인식하고 식별된 텍스트를 기계가 읽을 수 있는 문자 스트림으로 추출할 수 있습니다.

OCR JavaScript 요청 예제

예제를 실행하려면 다음의 과정을 따라하십시오:

  1. ocr.html 등의 이름으로 파일을 생성하고, 다음 예제 코드를 복사하여 붙여 넣은 다음 저장합니다.
  2. subscriptionKey의 값을 여러분이 발급받은 유효한 구독 키로 변경합니다.
  3. uriBase의 값을 구독 키를 발급받은 지역의 URL 주소로 변경합니다.
  4. 파일을 브라우저에 드래그 & 드랍합니다.
  5. Read image 버튼을 클릭합니다.
<!DOCTYPE html>
<html>
<head>
    <title>OCR Sample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    function processImage() {
        // **********************************************
        // *** Update or verify the following values. ***
        // **********************************************

        // Replace the subscriptionKey string value with your valid subscription key.
        var subscriptionKey = "13hc77781f7e4b19b5fcdd72a8df7156";

        // Replace or verify the region.
        //
        // You must use the same region in your REST API call as you used to obtain your subscription keys.
        // For example, if you obtained your subscription keys from the westus region, replace
        // "westcentralus" in the URI below with "westus".
        //
        // NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
        // a free trial subscription key, you should not need to change this region.
        var uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/ocr";

        // Request parameters.
        var params = {
            "language": "unk",
            "detectOrientation ": "true",
        };

        // Display the image.
        var sourceImageUrl = document.getElementById("inputImage").value;
        document.querySelector("#sourceImage").src = sourceImageUrl;

        // Perform the REST API call.
        $.ajax({
            url: uriBase + "?" + $.param(params),

            // Request headers.
            beforeSend: function(jqXHR){
                jqXHR.setRequestHeader("Content-Type","application/json");
                jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
            },

            type: "POST",

            // Request body.
            data: '{"url": ' + '"' + sourceImageUrl + '"}',
        })

        .done(function(data) {
            // Show formatted JSON on webpage.
            $("#responseTextArea").val(JSON.stringify(data, null, 2));
        })

        .fail(function(jqXHR, textStatus, errorThrown) {
            // Display error message.
            var errorString = (errorThrown === "") ? "Error. " : errorThrown + " (" + jqXHR.status + "): ";
            errorString += (jqXHR.responseText === "") ? "" : (jQuery.parseJSON(jqXHR.responseText).message) ? 
                jQuery.parseJSON(jqXHR.responseText).message : jQuery.parseJSON(jqXHR.responseText).error.message;
            alert(errorString);
        });
    };
</script>

<h1>Optical Character Recognition (OCR):</h1>
Enter the URL to an image of printed text, then click the <strong>Read image</strong> button.
<br><br>
Image to read: <input type="text" name="inputImage" id="inputImage" value="https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Atomist_quote_from_Democritus.png/338px-Atomist_quote_from_Democritus.png" />
<button onclick="processImage()">Read image</button>
<br><br>
<div id="wrapper" style="width:1020px; display:table;">
    <div id="jsonOutput" style="width:600px; display:table-cell;">
        Response:
        <br><br>
        <textarea id="responseTextArea" class="UIInput" style="width:580px; height:400px;"></textarea>
    </div>
    <div id="imageDiv" style="width:420px; display:table-cell;">
        Source image:
        <br><br>
        <img id="sourceImage" width="400" />
    </div>
</div>
</body>
</html>

OCR 결과 응답 살펴보기

성공 시 OCR 결과에는 텍스트, 영역의 경계를 이루는 사각형 좌표, 텍스트 라인 및 단어들이 포함되어 반환됩니다.

다음은 정상적으로 처리된 응답의 사례입니다:

{
  "language": "en",
  "textAngle": 0,
  "orientation": "Up",
  "regions": [
    {
      "boundingBox": "21,16,304,451",
      "lines": [
        {
          "boundingBox": "28,16,288,41",
          "words": [
            {
              "boundingBox": "28,16,288,41",
              "text": "NOTHING"
            }
          ]
        },
        {
          "boundingBox": "27,66,283,52",
          "words": [
            {
              "boundingBox": "27,66,283,52",
              "text": "EXISTS"
            }
          ]
        },
        {
          "boundingBox": "27,128,292,49",
          "words": [
            {
              "boundingBox": "27,128,292,49",
              "text": "EXCEPT"
            }
          ]
        },
        {
          "boundingBox": "24,188,292,54",
          "words": [
            {
              "boundingBox": "24,188,292,54",
              "text": "ATOMS"
            }
          ]
        },
        {
          "boundingBox": "22,253,297,32",
          "words": [
            {
              "boundingBox": "22,253,105,32",
              "text": "AND"
            },
            {
              "boundingBox": "144,253,175,32",
              "text": "EMPTY"
            }
          ]
        },
        {
          "boundingBox": "21,298,304,60",
          "words": [
            {
              "boundingBox": "21,298,304,60",
              "text": "SPACE."
            }
          ]
        },
        {
          "boundingBox": "26,387,294,37",
          "words": [
            {
              "boundingBox": "26,387,210,37",
              "text": "Everything"
            },
            {
              "boundingBox": "249,389,71,27",
              "text": "else"
            }
          ]
        },
        {
          "boundingBox": "127,431,198,36",
          "words": [
            {
              "boundingBox": "127,431,31,29",
              "text": "is"
            },
            {
              "boundingBox": "172,431,153,36",
              "text": "opinion."
            }
          ]
        }
      ]
    }
  ]
}

JavaScript와 Computer Vision API를 이용한 텍스트 인식하기

RecognizeText 메서드를 사용하면 이미지에 포함된 필기체 또는 인쇄된 텍스트를 감지하고 식별된 문자를 기계가 읽을 수 있는 문자 스트림으로 추출할 수 있습니다.

필기체 인식 JavaScript 예제

예제를 실행하려면 다음의 과정을 따라하십시오:

  1. handwriting.html 등의 이름으로 파일을 생성하고, 다음 예제 코드를 복사하여 붙여 넣은 다음 저장합니다.
  2. subscriptionKey의 값을 여러분이 발급받은 유효한 구독 키로 변경합니다.
  3. uriBase의 값을 구독 키를 발급받은 지역의 URL 주소로 변경합니다.
  4. 파일을 브라우저에 드래그 & 드랍합니다.
  5. Read image 버튼을 클릭합니다.
<!DOCTYPE html>
<html>
<head>
    <title>Handwriting Sample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    function processImage() {
        // **********************************************
        // *** Update or verify the following values. ***
        // **********************************************

        // Replace the subscriptionKey string value with your valid subscription key.
        var subscriptionKey = "13hc77781f7e4b19b5fcdd72a8df7156";

        // Replace or verify the region.
        //
        // You must use the same region in your REST API call as you used to obtain your subscription keys.
        // For example, if you obtained your subscription keys from the westus region, replace
        // "westcentralus" in the URI below with "westus".
        //
        // NOTE: Free trial subscription keys are generated in the westcentralus region, so if you are using
        // a free trial subscription key, you should not need to change this region.
        var uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/RecognizeText";

        // Request parameters.
        var params = {
            "handwriting": "true",
        };

        // Display the image.
        var sourceImageUrl = document.getElementById("inputImage").value;
        document.querySelector("#sourceImage").src = sourceImageUrl;

        // This operation requrires two REST API calls. One to submit the image for processing,
        // the other to retrieve the text found in the image. 
        //
        // Perform the first REST API call to submit the image for processing.
        $.ajax({
            url: uriBase + "?" + $.param(params),

            // Request headers.
            beforeSend: function(jqXHR){
                jqXHR.setRequestHeader("Content-Type","application/json");
                jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
            },

            type: "POST",

            // Request body.
            data: '{"url": ' + '"' + sourceImageUrl + '"}',
        })

        .done(function(data, textStatus, jqXHR) {
            // Show progress.
            $("#responseTextArea").val("Handwritten text submitted. Waiting 10 seconds to retrieve the recognized text.");

            // Note: The response may not be immediately available. Handwriting recognition is an
            // async operation that can take a variable amount of time depending on the length
            // of the text you want to recognize. You may need to wait or retry this GET operation.
            //
            // Wait ten seconds before making the second REST API call.
            setTimeout(function () { 
                // The "Operation-Location" in the response contains the URI to retrieve the recognized text.
                var operationLocation = jqXHR.getResponseHeader("Operation-Location");

                // Perform the second REST API call and get the response.
                $.ajax({
                    url: operationLocation,

                    // Request headers.
                    beforeSend: function(jqXHR){
                        jqXHR.setRequestHeader("Content-Type","application/json");
                        jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
                    },

                    type: "GET",
                })

                .done(function(data) {
                    // Show formatted JSON on webpage.
                    $("#responseTextArea").val(JSON.stringify(data, null, 2));
                })

                .fail(function(jqXHR, textStatus, errorThrown) {
                    // Display error message.
                    var errorString = (errorThrown === "") ? "Error. " : errorThrown + " (" + jqXHR.status + "): ";
                    errorString += (jqXHR.responseText === "") ? "" : (jQuery.parseJSON(jqXHR.responseText).message) ? 
                        jQuery.parseJSON(jqXHR.responseText).message : jQuery.parseJSON(jqXHR.responseText).error.message;
                    alert(errorString);
                });
            }, 10000);
        })

        .fail(function(jqXHR, textStatus, errorThrown) {
            // Put the JSON description into the text area.
            $("#responseTextArea").val(JSON.stringify(jqXHR, null, 2));

            // Display error message.
            var errorString = (errorThrown === "") ? "Error. " : errorThrown + " (" + jqXHR.status + "): ";
            errorString += (jqXHR.responseText === "") ? "" : (jQuery.parseJSON(jqXHR.responseText).message) ? 
                jQuery.parseJSON(jqXHR.responseText).message : jQuery.parseJSON(jqXHR.responseText).error.message;
            alert(errorString);
        });
    };
</script>
<h1>Read handwritten image image:</h1>
Enter the URL to an image of handwritten text, then click the <strong>Read image</strong> button.
<br><br>
Image to read: <input type="text" name="inputImage" id="inputImage" value="https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Cursive_Writing_on_Notebook_paper.jpg/800px-Cursive_Writing_on_Notebook_paper.jpg" />
<button onclick="processImage()">Read image</button>
<br><br>
<div id="wrapper" style="width:1020px; display:table;">
    <div id="jsonOutput" style="width:600px; display:table-cell;">
        Response:
        <br><br>
        <textarea id="responseTextArea" class="UIInput" style="width:580px; height:400px;"></textarea>
    </div>
    <div id="imageDiv" style="width:420px; display:table-cell;">
        Source image:
        <br><br>
        <img id="sourceImage" width="400" />
    </div>
</div>
</body>
</html>

필기체 인식 결과 응답 살펴보기

정상적으로 처리된 응답은 JSON 형식으로 반환됩니다. 필기체 인식 결과에는 감지된 텍스트, 영역의 경계를 이루는 사각형 좌표, 텍스트 라인 및 단어들이 포함되어 반환됩니다.

예제 응용 프로그램은 다음과 비슷한 결과를 출력할 것입니다:

{
  "status": "Succeeded",
  "recognitionResult": {
    "lines": [
      {
        "boundingBox": [
          2,
          84,
          783,
          96,
          782,
          154,
          1,
          148
        ],
        "text": "Pack my box with five dozen liquor jugs",
        "words": [
          {
            "boundingBox": [
              6,
              86,
              92,
              87,
              71,
              151,
              0,
              150
            ],
            "text": "Pack"
          },
          {
            "boundingBox": [
              86,
              87,
              172,
              88,
              150,
              152,
              64,
              151
            ],
            "text": "my"
          },
          {
            "boundingBox": [
              165,
              88,
              241,
              89,
              219,
              152,
              144,
              152
            ],
            "text": "box"
          },
          {
            "boundingBox": [
              234,
              89,
              343,
              90,
              322,
              154,
              213,
              152
            ],
            "text": "with"
          },
          {
            "boundingBox": [
              347,
              90,
              432,
              91,
              411,
              154,
              325,
              154
            ],
            "text": "five"
          },
          {
            "boundingBox": [
              432,
              91,
              538,
              92,
              516,
              154,
              411,
              154
            ],
            "text": "dozen"
          },
          {
            "boundingBox": [
              554,
              92,
              696,
              94,
              675,
              154,
              533,
              154
            ],
            "text": "liquor"
          },
          {
            "boundingBox": [
              710,
              94,
              800,
              96,
              800,
              154,
              688,
              154
            ],
            "text": "jugs"
          }
        ]
      },
      {
        "boundingBox": [
          2,
          52,
          65,
          46,
          69,
          89,
          7,
          95
        ],
        "text": "dog",
        "words": [
          {
            "boundingBox": [
              0,
              62,
              79,
              39,
              94,
              82,
              0,
              105
            ],
            "text": "dog"
          }
        ]
      },
      {
        "boundingBox": [
          6,
          2,
          771,
          13,
          770,
          75,
          5,
          64
        ],
        "text": "The quick brown fox jumps over the lazy",
        "words": [
          {
            "boundingBox": [
              8,
              4,
              92,
              5,
              77,
              71,
              0,
              71
            ],
            "text": "The"
          },
          {
            "boundingBox": [
              89,
              5,
              188,
              5,
              173,
              72,
              74,
              71
            ],
            "text": "quick"
          },
          {
            "boundingBox": [
              188,
              5,
              323,
              6,
              308,
              73,
              173,
              72
            ],
            "text": "brown"
          },
          {
            "boundingBox": [
              316,
              6,
              386,
              6,
              371,
              73,
              302,
              73
            ],
            "text": "fox"
          },
          {
            "boundingBox": [
              396,
              7,
              508,
              7,
              493,
              74,
              381,
              73
            ],
            "text": "jumps"
          },
          {
            "boundingBox": [
              501,
              7,
              604,
              8,
              589,
              75,
              487,
              74
            ],
            "text": "over"
          },
          {
            "boundingBox": [
              600,
              8,
              673,
              8,
              658,
              75,
              586,
              75
            ],
            "text": "the"
          },
          {
            "boundingBox": [
              670,
              8,
              800,
              9,
              787,
              76,
              655,
              75
            ],
            "text": "lazy"
          }
        ]
      }
    ]
  }
}