Computer Vision API JavaScript 자습서

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

본 자습서에서는 Microsoft Cognitive Services의 Computer Vision REST API 기능을 살펴봅니다.

Computer Vision REST API를 이용해서 광학 문자 인식(OCR)을 수행하거나 스마트하게 자른 썸네일을 생성하고, 이미지에서 얼굴을 비롯한 다양한 시각적 특징들을 감지해서 분류하고, 태깅하고, 설명하는 JavaScript 응용 프로그램을 살펴봅니다. 본문의 예제 응용 프로그램은 이미지의 URL을 전달하거나 로컬에 저장된 이미지 파일을 제출하는 방식으로 동작합니다. 이 오픈 소스 예제 응용 프로그램을 템플릿으로 삼아서 JavaScript로 Computer Vision REST API를 활용하는 자신만의 개별 응용 프로그램을 개발해도 무방합니다.

본 자습서를 위한 JavaScript 폼 응용 프로그램은 이미 준비되어 있지만, 아직 실제 기능은 구현되지 않은 상태입니다. 본문에서는 이 예제 응용 프로그램에 Computer Vision REST API 관련 코드를 하나씩 추가해보면서 응용 프로그램의 기능을 완성할 것입니다.

요구 사항

플랫폼 요구 사항

본문의 예제 응용 프로그램은 간단한 텍스트 편집기를 이용해서 개발되었습니다.

Computer Vision API 구독 및 구독 키 발급받기

예제 응용 프로그램을 직접 실행해보려면, 먼저 Microsoft Cognitive Services의 일부인 Computer Vision API에 가입해야 합니다. 구독 및 구독 키 관리에 관한 세부적인 사항들은 Cognitive Services 체험하기 페이지를 참고하시기 바랍니다. 본 자습서에서는 발급된 기본 키와 보조 키, 모두 사용 가능합니다.

자습서 프로젝트 다운로드

Cognitive Services JavaScript Computer Vision Tutorial 리파지터리를 복제하거나, .zip 파일을 다운로드 받아서 빈 디렉터리에 압축을 풉니다.

모든 자습서 코드가 추가되어 있는 미리 준비된 완성된 자습서는 Completed 폴더에서 살펴보실 수 있습니다.

자습서 코드 추가하기

본문의 JavaScript 응용 프로그램은 각 기능들에 대한 여섯 개의 .html 파일로 구성되어 있으며, 각각의 파일은 Computer Vision의 서로 다른 기능들을 (분석, OCR 등) 보여줍니다. 여섯 개의 자습서 절들은 서로 상호 의존적이지 않으므로, 한 절의 코드만 추가하거나, 여섯 개 절들의 코드를 모두를 추가하거나, 또는 한 두 절의 코드만 추가할 수도 있습니다. 물론 절을 추가하는 순서도 전혀 상관 없습니다.

이미지 분석하기

Computer Vision API의 분석 기능은 이미지에 포함된 2,000 가지 이상의 인식 가능한 개체, 생명체, 풍경 및 동작을 분석합니다. 분석 기능은 처리가 완료되면 설명 태그, 색상 분석, 캡션 등으로 이미지를 설명하는 JSON 개체를 반환합니다.

자습서 응용 프로그램의 분석 기능을 구현하려면, 다음의 단계들을 수행합니다:

분석 단계 1: 페이지 버튼에 대한 이벤트 처리기 추가하기

텍스트 편집기로 analyze.html 파일을 열고, 파일의 맨 아래 부분에 위치한 analyzeButtonClick 함수를 찾습니다.

analyzeButtonClick 이벤트 처리기 함수는 페이지를 초기화하고, URL로 지정한 이미지를 출력한 다음, 이미지를 분석하기 위한 AnalyzeImage 메서드를 호출합니다.

다음 코드를 analyzeButtonClick 함수에 복사해서 붙여 넣습니다.

function analyzeButtonClick() {

    // Clear the display fields.
    $("#sourceImage").attr("src", "#");
    $("#responseTextArea").val("");
    $("#captionSpan").text("");

    // Display the image.
    var sourceImageUrl = $("#inputImage").val();
    $("#sourceImage").attr("src", sourceImageUrl);

    AnalyzeImage(sourceImageUrl, $("#responseTextArea"), $("#captionSpan"));
}

분석 단계 2: REST API 호출 래퍼 추가하기

AnalyzeImage 함수는 이미지를 분석하는 REST API 호출을 래핑합니다. 결과가 성공적으로 반환되면, 분석 결과가 정리된 JSON을 지정한 텍스트 영역에 표시하고 지정된 위치에 캡션을 출력합니다.

다음 AnalyzeImage 함수를 복사해서 analyzeButtonClick 함수 바로 아래에 붙여 넣습니다.

/* Analyze the image at the specified URL by using Microsoft Cognitive Services Analyze Image API.
 * @param {string} sourceImageUrl - The URL to the image to analyze.
 * @param {<textarea> element} responseTextArea - The text area to display the JSON string returned
 *                             from the REST API call, or to display the error message if there was 
 *                             an error.
 * @param {<span> element} captionSpan - The span to display the image caption.
 */
function AnalyzeImage(sourceImageUrl, responseTextArea, captionSpan) {
    // Request parameters.
    var params = {
        "visualFeatures": "Categories,Description,Color",
        "details": "",
        "language": "en",
    };

    // Perform the REST API call.
    $.ajax({
        url: common.uriBasePreRegion + 
             $("#subscriptionRegionSelect").val() + 
             common.uriBasePostRegion + 
             common.uriBaseAnalyze +
             "?" + 
             $.param(params),

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

        type: "POST",

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

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

        // Extract and display the caption and confidence from the first caption in the description object.
        if (data.description && data.description.captions) {
            var caption = data.description.captions[0];

            if (caption.text && caption.confidence) {
                captionSpan.text("Caption: " + caption.text +
                    " (confidence: " + caption.confidence + ").");
            }
        }
    })

    .fail(function(jqXHR, textStatus, errorThrown) {
        // Prepare the error string.
        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;

        // Put the error JSON in the response textarea.
        responseTextArea.val(JSON.stringify(jqXHR, null, 2));

        // Show the error message.
        alert(errorString);
    });
}

분석 단계 3: 응용 프로그램 실행하기

analyze.html 파일을 저장하고 웹 브라우저에서 실행합니다. Subscription Key 필드에는 구독 키를 입력하고, Subscription Region 필드가 올바른 지역을 선택하고 있는지 확인합니다. 분석하고자 하는 이미지의 URL을 입력한 다음, Analyze Image 버튼을 클릭해서 이미지를 분석하고 그 결과를 확인합니다.

랜드마크 식별하기

Computer Vision의 랜드마크 기능은 이미지에 포함된 산이나 유명한 빌딩 같은, 자연적 또는 인공적 랜드마크를 분석합니다. 그리고 처리가 완료되면 이미지에서 발견한 랜드마크를 식별하는 JSON 개체를 반환합니다.

자습서 응용 프로그램의 랜드마크 기능을 구현하려면, 다음의 단계들을 수행합니다:

랜드마크 단계 1: 페이지 버튼에 대한 이벤트 처리기 추가하기

텍스트 편집기로 landmark.html 파일을 열고, 파일의 맨 아래 부분에 위치한 landmarkButtonClick 함수를 찾습니다.

landmarkButtonClick 이벤트 처리기 함수는 페이지를 초기화하고, URL로 지정한 이미지를 출력한 다음, 이미지를 분석하기 위한 IdentifyLandmarks 메서드를 호출합니다.

다음 코드를 landmarkButtonClick 함수에 복사해서 붙여 넣습니다.

function landmarkButtonClick() {

    // Clear the display fields.
    $("#sourceImage").attr("src", "#");
    $("#responseTextArea").val("");
    $("#captionSpan").text("");

    // Display the image.
    var sourceImageUrl = $("#inputImage").val();
    $("#sourceImage").attr("src", sourceImageUrl);

    IdentifyLandmarks(sourceImageUrl, $("#responseTextArea"), $("#captionSpan"));
}

랜드마크 단계 2: REST API 호출 래퍼 추가하기

IdentifyLandmarks 함수는 이미지를 분석하는 REST API 호출을 래핑합니다. 결과가 성공적으로 반환되면, 분석 결과가 정리된 JSON을 지정한 텍스트 영역에 표시하고 지정된 위치에 캡션을 출력합니다.

다음 IdentifyLandmarks 함수를 복사해서 landmarkButtonClick 함수 바로 아래에 붙여 넣습니다.

/* Identify landmarks in the image at the specified URL by using Microsoft Cognitive Services 
 * Landmarks API.
 * @param {string} sourceImageUrl - The URL to the image to analyze for landmarks.
 * @param {<textarea> element} responseTextArea - The text area to display the JSON string returned
 *                             from the REST API call, or to display the error message if there was 
 *                             an error.
 * @param {<span> element} captionSpan - The span to display the image caption.
 */
function IdentifyLandmarks(sourceImageUrl, responseTextArea, captionSpan) {
    // Request parameters.
    var params = {
        "model": "landmarks"
    };

    // Perform the REST API call.
    $.ajax({
        url: common.uriBasePreRegion + 
             $("#subscriptionRegionSelect").val() + 
             common.uriBasePostRegion + 
             common.uriBaseLandmark +
             "?" + 
             $.param(params),

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

        type: "POST",

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

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

        // Extract and display the caption and confidence from the first caption in the description object.
        if (data.result && data.result.landmarks) {
            var landmark = data.result.landmarks[0];

            if (landmark.name && landmark.confidence) {
                captionSpan.text("Landmark: " + landmark.name +
                    " (confidence: " + landmark.confidence + ").");
            }
        }
    })

    .fail(function(jqXHR, textStatus, errorThrown) {
        // Prepare the error string.
        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;

        // Put the error JSON in the response textarea.
        responseTextArea.val(JSON.stringify(jqXHR, null, 2));

        // Show the error message.
        alert(errorString);
    });
}

랜드마크 단계 3: 응용 프로그램 실행하기

landmark.html 파일을 저장하고 웹 브라우저에서 실행합니다. Subscription Key 필드에는 구독 키를 입력하고, Subscription Region 필드가 올바른 지역을 선택하고 있는지 확인합니다. 분석하고자 하는 이미지의 URL을 입력한 다음, Analyze Image 버튼을 클릭해서 이미지를 분석하고 그 결과를 확인합니다.

유명인사 식별하기

Computer Vision의 유명인사 기능은 이미지에 포함된 유명한 사람들을 분석합니다. 그리고 처리가 완료되면 이미지에서 발견된 유명인사를 식별하는 JSON 개체를 반환합니다.

자습서 응용 프로그램의 유명인사 기능을 구현하려면, 다음의 단계들을 수행합니다:

유명인사 단계 1: 페이지 버튼에 대한 이벤트 처리기 추가하기

텍스트 편집기로 celebrities.html 파일을 열고, 파일의 맨 아래 부분에 위치한 celebritiesButtonClick 함수를 찾습니다.

celebritiesButtonClick 이벤트 처리기 함수는 페이지를 초기화하고, URL로 지정한 이미지를 출력한 다음, 이미지를 분석하기 위한 IdentifyCelebrities 메서드를 호출합니다.

다음 코드를 celebritiesButtonClick 함수에 복사해서 붙여 넣습니다.

function celebritiesButtonClick() {

    // Clear the display fields.
    $("#sourceImage").attr("src", "#");
    $("#responseTextArea").val("");
    $("#captionSpan").text("");

    // Display the image.
    var sourceImageUrl = $("#inputImage").val();
    $("#sourceImage").attr("src", sourceImageUrl);

    IdentifyCelebrities(sourceImageUrl, $("#responseTextArea"), $("#captionSpan"));
}

유명인사 단계 2: REST API 호출 래퍼 추가하기

IdentifyCelebrities 함수는 이미지를 분석하는 REST API 호출을 래핑합니다. 결과가 성공적으로 반환되면, 분석 결과가 정리된 JSON을 지정한 텍스트 영역에 표시하고 지정된 위치에 캡션을 출력합니다.

/* Identify celebrities in the image at the specified URL by using Microsoft Cognitive Services 
 * Celebrities API.
 * @param {string} sourceImageUrl - The URL to the image to analyze for celebrities.
 * @param {<textarea> element} responseTextArea - The text area to display the JSON string returned
 *                             from the REST API call, or to display the error message if there was 
 *                             an error.
 * @param {<span> element} captionSpan - The span to display the image caption.
 */
function IdentifyCelebrities(sourceImageUrl, responseTextArea, captionSpan) {
    // Request parameters.
    var params = {
        "model": "celebrities"
    };

    // Perform the REST API call.
    $.ajax({
        url: common.uriBasePreRegion + 
             $("#subscriptionRegionSelect").val() + 
             common.uriBasePostRegion + 
             common.uriBaseCelebrities +
             "?" + 
             $.param(params),

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

        type: "POST",

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

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

        // Extract and display the caption and confidence from the first caption in the description object.
        if (data.result && data.result.celebrities) {
            var celebrity = data.result.celebrities[0];

            if (celebrity.name && celebrity.confidence) {
                captionSpan.text("Celebrity name: " + celebrity.name +
                    " (confidence: " + celebrity.confidence + ").");
            }
        }
    })

    .fail(function(jqXHR, textStatus, errorThrown) {
        // Prepare the error string.
        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;

        // Put the error JSON in the response textarea.
        responseTextArea.val(JSON.stringify(jqXHR, null, 2));

        // Show the error message.
        alert(errorString);
    });
}

유명인사 단계 3: 응용 프로그램 실행하기

celebrities.html 파일을 저장하고 웹 브라우저에서 실행합니다. Subscription Key 필드에는 구독 키를 입력하고, Subscription Region 필드가 올바른 지역을 선택하고 있는지 확인합니다. 분석하고자 하는 이미지의 URL을 입력한 다음, Analyze Image 버튼을 클릭해서 이미지를 분석하고 그 결과를 확인합니다.

지능적으로 썸네일 생성하기

Computer Vision의 썸네일 기능은 이미지의 썸네일을 생성합니다. 또한 Smart Crop 기능을 사용해서 이미지의 관심 영역을 식별하고 이 영역을 썸네일의 중앙에 배치함으로써 더 보기 좋은 썸네일을 생성할 수도 있습니다.

자습서 응용 프로그램의 썸네일 기능을 구현하려면, 다음의 단계들을 수행합니다:

역주

제공되는 thumbnail.html 파일의 예제 소스에 쌍따옴표가 누락된 버그가 존재합니다. 27 번째 줄의 id 속성에 쌍따옴표를 추가해야 합니다.

썸네일 단계 1: 페이지 버튼에 대한 이벤트 처리기 추가하기

텍스트 편집기로 thumbnail.html 파일을 열고, 파일의 맨 아래 부분에 위치한 thumbnailButtonClick 함수를 찾습니다.

thumbnailButtonClick 이벤트 처리기 함수는 페이지를 초기화하고, URL로 지정한 이미지를 출력한 다음, 썸네일을 생성하기 위해서 getThumbnail 함수를 호출하는데, 스마트 자르기 옵션을 지정한 상태로 한 번 호출하고, 다시 옵션을 지정하지 않은 상태로 한 번 호출해서 모두 두 번 호출합니다.

다음 코드를 thumbnailButtonClick 함수에 복사해서 붙여 넣습니다.

function thumbnailButtonClick() {

    // Clear the display fields.
    document.getElementById("sourceImage").src = "#";
    document.getElementById("thumbnailImageSmartCrop").src = "#";
    document.getElementById("thumbnailImageNonSmartCrop").src = "#";
    document.getElementById("responseTextArea").value = "";
    document.getElementById("captionSpan").text = "";

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

    // Get a smart cropped thumbnail.
    getThumbnail (sourceImageUrl, true, document.getElementById("thumbnailImageSmartCrop"), 
        document.getElementById("responseTextArea"));

    // Get a non-smart-cropped thumbnail.
    getThumbnail (sourceImageUrl, false, document.getElementById("thumbnailImageNonSmartCrop"),
        document.getElementById("responseTextArea"));
}

썸네일 단계 2: REST API 호출 래퍼 추가하기

getThumbnail 함수는 썸네일을 생성하는 REST API 호출을 래핑합니다. 결과가 성공적으로 반환되면, 생성된 썸네일이 지정한 이미지 요소에 출력됩니다.

다음 getThumbnail 함수를 복사해서 thumbnailButtonClick 함수 바로 아래에 붙여 넣습니다.

/* Get a thumbnail of the image at the specified URL by using Microsoft Cognitive Services
 * Thumbnail API.
 * @param {string} sourceImageUrl URL to image.
 * @param {boolean} smartCropping Set to true to use the smart cropping feature which crops to the
 *                                more interesting area of an image; false to crop for the center
 *                                of the image.
 * @param {<img> element} imageElement The img element in the DOM which will display the thumnail image.
 * @param {<textarea> element} responseTextArea - The text area to display the Response Headers returned
 *                             from the REST API call, or to display the error message if there was 
 *                             an error.
 */
function getThumbnail (sourceImageUrl, smartCropping, imageElement, responseTextArea) {
    // Create the HTTP Request object.
    var xhr = new XMLHttpRequest();

    // Request parameters.
    var params = "width=100&height=150&smartCropping=" + smartCropping.toString();

    // Build the full URI.
    var fullUri = common.uriBasePreRegion + 
                  document.getElementById("subscriptionRegionSelect").value + 
                  common.uriBasePostRegion + 
                  common.uriBaseThumbnail +
                  "?" + 
                  params;

    // Identify the request as a POST, with the URI and parameters.
    xhr.open("POST", fullUri);

    // Add the request headers.
    xhr.setRequestHeader("Content-Type","application/json");
    xhr.setRequestHeader("Ocp-Apim-Subscription-Key", 
        encodeURIComponent(document.getElementById("subscriptionKeyInput").value));

    // 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);
                responseTextArea.value = JSON.stringify(xhr.getAllResponseHeaders(), null, 2);

                // Show thumbnail image.
                var urlCreator = window.URL || window.webkitURL;
                var imageUrl = urlCreator.createObjectURL(this.response);
                imageElement.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) => {
                    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 + '"}');
}

썸네일 단계 3: 응용 프로그램 실행하기

thumbnail.html 파일을 저장하고 웹 브라우저에서 실행합니다. Subscription Key 필드에는 구독 키를 입력하고, Subscription Region 필드가 올바른 지역을 선택하고 있는지 확인합니다. 썸네일을 생성하고자 하는 이미지의 URL을 입력한 다음, Generate Thumbnails 버튼을 클릭해서 썸네일을 얻고 그 결과를 확인합니다.

인쇄된 텍스트 읽기 (OCR)

Computer Vision의 광학 문자 인식 (OCR, Optical Character Recognition) 기능은 이미지에 포함된 인쇄된 텍스트를 분석합니다. 그리고 처리가 완료되면 이미지에서 발견한 텍스트와 해당 텍스트의 이미지 상의 좌표가 담긴 JSON 개체를 반환합니다.

자습서 응용 프로그램의 광학 문자 인식 기능을 구현하려면, 다음의 단계들을 수행합니다:

OCR 단계 1: 페이지 버튼에 대한 이벤트 처리기 추가하기

텍스트 편집기로 ocr.html 파일을 열고, 파일의 맨 아래 부분에 위치한 ocrButtonClick 함수를 찾습니다.

ocrButtonClick 이벤트 처리기 함수는 페이지를 초기화하고, URL로 지정한 이미지를 출력한 다음, 이미지를 분석하기 위한 ReadOcrImage 메서드를 호출합니다.

다음 코드를 ocrButtonClick 함수에 복사해서 붙여 넣습니다.

function ocrButtonClick() {

    // Clear the display fields.
    $("#sourceImage").attr("src", "#");
    $("#responseTextArea").val("");
    $("#captionSpan").text("");

    // Display the image.
    var sourceImageUrl = $("#inputImage").val();
    $("#sourceImage").attr("src", sourceImageUrl);

    ReadOcrImage(sourceImageUrl, $("#responseTextArea"));
}

OCR 단계 2: REST API 호출 래퍼 추가하기

ReadOcrImage 함수는 이미지를 분석하는 REST API 호출을 래핑합니다. 결과가 성공적으로 반환되면, 감지된 텍스트와 해당 텍스트의 좌표가 정리된 JSON을 지정한 텍스트 영역에 출력합니다.

다음 ReadOcrImage 함수를 복사해서 ocrButtonClick 함수 바로 아래에 붙여 넣습니다.

/* Recognize and read printed text in an image at the specified URL by using Microsoft Cognitive 
 * Services OCR API.
 * @param {string} sourceImageUrl - The URL to the image to analyze for printed text.
 * @param {<textarea> element} responseTextArea - The text area to display the JSON string returned
 *                             from the REST API call, or to display the error message if there was 
 *                             an error.
 */
function ReadOcrImage(sourceImageUrl, responseTextArea) {
    // Request parameters.
    var params = {
        "language": "unk",
        "detectOrientation ": "true",
    };

    // Perform the REST API call.
    $.ajax({
        url: common.uriBasePreRegion + 
             $("#subscriptionRegionSelect").val() + 
             common.uriBasePostRegion + 
             common.uriBaseOcr +
             "?" + 
             $.param(params),

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

        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) {
        // 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);
    });
}

OCR 단계 3: 응용 프로그램 실행하기

ocr.html 파일을 저장하고 웹 브라우저에서 실행합니다. Subscription Key 필드에는 구독 키를 입력하고, Subscription Region 필드가 올바른 지역을 선택하고 있는지 확인합니다. 텍스트를 분석하고자 하는 이미지의 URL을 입력한 다음, Read Image 버튼을 클릭해서 이미지를 분석하고 그 결과를 확인합니다.

필기체 텍스트 읽기 (필기 인식하기)

Computer Vision의 필기체 인식 기능은 이미지에 포함된 필기체 텍스트를 분석합니다. 그리고 처리가 완료되면 이미지에서 발견한 텍스트와 해당 텍스트의 이미지 상의 좌표가 담긴 JSON 개체를 반환합니다.

자습서 응용 프로그램의 필기체 인식 기능을 구현하려면, 다음의 단계들을 수행합니다:

역주

현재 필기체 인식 기능은 영어만 지원됩니다.

필기체 인식 단계 1: 페이지 버튼에 대한 이벤트 처리기 추가하기

텍스트 편집기로 handwriting.html 파일을 열고, 파일의 맨 아래 부분에 위치한 handwritingButtonClick 함수를 찾습니다.

handwritingButtonClick 이벤트 처리기 함수는 페이지를 초기화하고, URL로 지정한 이미지를 출력한 다음, 이미지를 분석하기 위한 HandwritingImage 메서드를 호출합니다.

다음 코드를 handwritingButtonClick 함수에 복사해서 붙여 넣습니다.

function handwritingButtonClick() {

    // Clear the display fields.
    $("#sourceImage").attr("src", "#");
    $("#responseTextArea").val("");

    // Display the image.
    var sourceImageUrl = $("#inputImage").val();
    $("#sourceImage").attr("src", sourceImageUrl);

    ReadHandwrittenImage(sourceImageUrl, $("#responseTextArea"));
}

필기체 인식 단계 2: REST API 호출 래퍼 추가하기

ReadHandwrittenImage 함수는 이미지를 분석하기 위해서 필요한 두 가지 REST API 호출을 래핑합니다. 필기체 인식은 다소 시간이 소요되는 처리이기 때문에, 처리 과정이 두 단계로 나눠집니다. 먼저 첫 번째 호출은 분석할 이미지를 제출하고, 이어지는 두 번째 호출은 처리가 끝나면 감지된 텍스트를 받아옵니다.

그리고 결과가 반환되면, 텍스트 및 해당 텍스트의 위치를 설명하는 정리된 JSON을 지정한 텍스트 영역에 출력합니다.

다음 ReadHandwrittenImage 함수를 복사해서 handwritingButtonClick 함수 바로 아래에 붙여 넣습니다.

/* Recognize and read text from an image of handwriting at the specified URL by using Microsoft 
 * Cognitive Services Recognize Handwritten Text API.
 * @param {string} sourceImageUrl - The URL to the image to analyze for handwriting.
 * @param {<textarea> element} responseTextArea - The text area to display the JSON string returned
 *                             from the REST API call, or to display the error message if there was 
 *                             an error.
 */
function ReadHandwrittenImage(sourceImageUrl, responseTextArea) {
    // Request parameters.
    var params = {
        "handwriting": "true",
    };

    // 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: common.uriBasePreRegion + 
             $("#subscriptionRegionSelect").val() + 
             common.uriBasePostRegion + 
             common.uriBaseHandwriting +
             "?" + 
             $.param(params),

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

        type: "POST",

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

    .done(function(data, textStatus, jqXHR) {
        // Show progress.
        responseTextArea.val("Handwritten image submitted.");

        // 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.
        //
        // Try once per second for up to ten seconds to receive the result.
        var tries = 10;
        var waitTime = 100;
        var taskCompleted = false;

        var timeoutID = setInterval(function () { 
            // Limit the number of calls.
            if (--tries <= 0) {
                window.clearTimeout(timeoutID);
                responseTextArea.val("The response was not available in the time allowed.");
                return;
            }

            // 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",
                        encodeURIComponent($("#subscriptionKeyInput").val()));
                },

                type: "GET",
            })

            .done(function(data) {
                // If the result is not yet available, return.
                if (data.status && (data.status === "NotStarted" || data.status === "Running")) {
                    return;
                }

                // Show formatted JSON on webpage.
                responseTextArea.val(JSON.stringify(data, null, 2));

                // Indicate the task is complete and clear the timer.
                taskCompleted = true;
                window.clearTimeout(timeoutID);
            })

            .fail(function(jqXHR, textStatus, errorThrown) {
                // Indicate the task is complete and clear the timer.
                taskCompleted = true;
                window.clearTimeout(timeoutID);

                // 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);
            });
        }, waitTime);
    })

    .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);
    });
}

필기체 인식 단계 3: 응용 프로그램 실행하기

handwriting.html 파일을 저장하고 웹 브라우저에서 실행합니다. Subscription Key 필드에는 구독 키를 입력하고, Subscription Region 필드가 올바른 지역을 선택하고 있는지 확인합니다. 텍스트를 분석하고자 하는 이미지의 URL을 입력한 다음, Read Image 버튼을 클릭해서 이미지를 분석하고 그 결과를 확인합니다.

관련 자료