C#으로 Windows 10 OCR 사용하기

남정현·2020년 10월 16일
2

Beyond the Windows

목록 보기
1/1
post-thumbnail

익히 알려져있는대로, Windows 10과 Windows Server 2016에는 내장된 OCR 기능이 있습니다. 그리고 이 엔진은 Microsoft Research의 프로젝트 중 하나인 Oxford 프로젝트의 산출물이자, 동시에 최근 Microsoft Azure의 Cognitive Service로도 사용할 수 있습니다.

원하는 성능 기준이나 상황에 따라서 어떤 OCR 엔진을 사용할 것인지는 그 때 마다 적절한 선택지가 달라지기 마련입니다. 그 중에서도 이번 아티클은, 저의 관점에서 가장 이상적이라고 생각했던 시나리오인 “데스크탑 환경”에서의 OCR 사용에 초점을 맞추어 사용 방법을 작성해보았습니다.

준비물

Windows 10의 OCR은 Universal Windows Platform (UWP) App의 API로 사용할 수 있도록 되어있습니다. 그런데 UWP API를 사용하려면 UWP 어플리케이션이 아니면 사용이 불가능하지 않는가 라고 오해하시는 경우가 많이 있는데, 그렇지 않습니다.

  • Windows 10 SDK 설치 (사용하고 있는 Windows 10의 버전과 일치하는 SDK를 찾아서 설치하시면 무난합니다.)
  • Visual Studio 2010 이상의 IDE (.NET 4.0 이상을 지원하는 IDE를 권장합니다.) 또는 LINQPAD

실습의 간편함을 위하여 저는 LINQPAD를 기준으로 이 아티클을 작성하였습니다.

코드 작성 전의 준비 사항

UWP API를 C#에서 사용하려면, WINMD 레퍼런스 파일이 필요합니다. %programfiles(x86)%\Windows Kits\10\UnionMetadata 폴더에서 OCR API까지 포함된 WINMD 레퍼런스 파일을 찾을 수 있으며, 이것을 보통 클래스 라이브러리 참조를 추가하듯 동일하게 추가하여 사용할 수 있습니다.

그리고 C#과 .NET Framework 환경에서 UWP API와 상호 운용을 편하게 하기 위한 도우미 코드를 System.Runtime 어셈블리와 System.Runtime.WindowsRuntime 어셈블리에서 포함하고 있습니다. 아래와 같이 참조 목록을 완성합니다.

그리고 OCR에서 지원하는 언어로 한국어를 포함하려면, Windows 10의 설정 앱의 “선택적 기능 관리” 메뉴에서 다음과 같이 한국어 언어 팩을 설치하도록 합니다.

  • 이 단위의 설정 메뉴는 기존의 제어판이나 MMC 콘솔에서는 접근할 수 없으니 착오 없으시기 바랍니다.
  • OCR 설치 과정에서 Windows 업데이트 서버에서 파일을 다운로드받는 과정이 필요하므로, 인터넷 연결을 사전에 확인해야 합니다.

코드 작성하기

Windows 10의 OCR 엔진의 기본적인 사용 방법은 다음과 같습니다.

using Windows.Globalization;
using Windows.Graphics.Imaging;
using Windows.Media.Ocr;
using Windows.Storage;
using Windows.Storage.Streams;

...

var language = new Language(“ko”);
if (!OcrEngine.IsLanguageSupported(language))
{
  throw new Exception($”{language.LanguageTag} is not supported in this system.);
}

var stream = File.OpenRead(“…”);
var decoder = await BitmapDecoder.CreateAsync(stream.AsRandomAccessStream());
var bitmap = await decoder.GetSoftwareBitmapAsync();
var engine = OcrEngine.TryCreateFromLanguage(language);
var ocrResult = await engine.RecognizeAsync(bitmap).AsTask();

대략적인 순서는 다음과 같습니다.

  1. OCR 엔진에서 지원할 언어가 시스템에 설치되어있고, 사용 가능한 상태인지 확인합니다.
  2. .NET에서 파일 스트림을 열고, 이것을 UWP의 RandomAccessStream으로 캐스팅합니다.
  3. BitmapDecoder로 Stream을 전달하여 이미지를 로드합니다.
  4. 만들어진 SoftwareBitmap 개체를 OCR 엔진에 전달하여 OCR 결과를 반환받습니다.

UWP API를 이용하여 파일을 직접 액세스하려고 하는 경우에는, API가 한정되어있어 제약 사항이 많습니다. 그래서 기존의 .NET API를 이용하여 편리하게 콘텐츠를 준비한 다음, 이것을 UWP API로 전달하여 처리하도록 한 것입니다.

만약 OCR 품질의 개선을 위하여 이미지 전처리를 OpenCV나 AForge.NET 혹은 ImageMagick 같은 외부 도구를 활용하고자 하는 경우에는, UWP API로 스트림을 넘기기 전에 처리를 완료하시면 되겠습니다.

OCR 처리 결과 살펴보기

그렇다면 실제 OCR 처리 성능은 어느정도 일까요? 흔히 OCR을 가지고 처리할 수 있을 것으로 기대하는 영수증을 샘플로 돌려보았습니다.

이미지의 상태에 따라 상황이 다를 수 있지만, 약간의 보정을 해준다면 만족스러운 결과를 낼 수도 있을거란 기대가 듭니다.

결론

OCR은 최근 딥 러닝에 대한 붐이 일면서 Speech-To-Text와 더불어 실 생활에 접목할 수 있는 응용 기술로 다시 주목을 받고 있습니다. 실제로 활용 가능한 목적이 분명한 OCR 엔진을 만드는 것과는 별개로, 일상적인 수준에서 활용할 수 있는 OCR 엔진을 찾고자 하는 경우 Windows 10의 OCR 엔진도 적절한 선택지가 될 수 있습니다.

그리고 UWP의 새로운 API들도 WINMD 메타데이터 참조를 이용하여 쉽게 호출해서 쓸 수 있으니 다른 API들도 살펴보시고 유용한 기능을 쉽게 찾아 개발하는데 도움이 될 수 있도록 응용해보시는 것도 좋겠습니다.

1개의 댓글

comment-user-thumbnail
2020년 10월 16일

신기한기능이네요! 혹시 프로젝트 전체코드를 볼수있을까요? .net core app 에서도 활용할수있을까요?

답글 달기