Xamarin(자마린) Android Tesseract OCR 어플 만들기 - 소스코드 및 결과
* Xamarin(자마린) Android Tesseract OCR 어플 만들기 - 개발 환경설정 에서 이어짐.
Android Studio 개발을 진행중이라 포스팅이 늦었다. 정리가 되면 올릴 예정.
글자 인식 라이브러리인 Tesseract를 사용하기 위해서는 확장자 .traineddata 형식의 언어데이터가 필요하다.
여기서 다운받을 수 있다.
https://github.com/tesseract-ocr/tessdata
테스트용으로 kor, eng를 다운받았다.
다운받은 파일들은 Android 프로젝트 안에 있는 Assets 폴더에 tessdata라는 폴더를 생성하고 넣어준다.
Android 프로젝트에 있는 MainActivity.cs 를 작성한다.
using System;
using Android.App;
using Android.Content.PM;
using Android.OS;
using TinyIoC;
using Tesseract;
using Tesseract.Droid;
using XLabs.Ioc;
using XLabs.Ioc.TinyIOC;
using XLabs.Platform.Device;
namespace Xocr.Droid
{
[Activity(Label = "Xocr", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var container = TinyIoCContainer.Current;
container.Register<IDevice>(AndroidDevice.CurrentDevice);
container.Register<ITesseractApi>((cont, parameters) =>
{
return new TesseractApi(ApplicationContext, Tesseract.Droid.AssetsDeployment.OncePerInitialization);
});
Resolver.SetResolver(new TinyResolver(container));
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
앞에서 다운받았던 라이브러리들이 사용되는데, Ioc는 디자인 틀과 동시에 Register 함수를 통해 인스턴트를 등록시키는 역할을 한다. 이를 통해 tessdata를 불러와 TesseractAPI를 등록하는 작업을 수행한다.
+
OncePerInitialization이 무엇인가 하고 소스를 확인해보니, Init할때마다 tessdata를 업데이트하기 때문에 속도가 느리므로 디버그 모드에서 사용하라고 한다.
그 반대인 OncePerVersion는 tessdata를 업데이트하지 않지만 속도가 빠르므로 실제 프로그램에서 사용하라는 것 같다.
테스트해보니 첫 수행에서는 별 차이 없는 속도고, 두번째 이후부터 차이가 생기는 것 같다.
이제 PCL 프로젝트의 MainPage.xaml.cs를 작성한다.
using System;
using System.Threading.Tasks;
using Tesseract;
using Xamarin.Forms;
using XLabs.Ioc;
using XLabs.Platform.Device;
using XLabs.Platform.Services.Media;
namespace Xocr
{
public partial class MainPage : ContentPage
{
private Button _takePictureButton;
private Label _recognizedTextLabel;
private Image _takenImage;
private readonly ITesseractApi _tesseractApi;
private readonly IDevice _device;
public MainPage()
{
InitializeComponent();
//TesseractAPI
_tesseractApi = Resolver.Resolve<ITesseractApi>();
_device = Resolver.Resolve<IDevice>();
//UI 생성
BuildUi();
//(버튼)이벤트 생성
WireEvents();
}
private void BuildUi()
{
// 버튼 생성
_takePictureButton = new Button
{
Text = "New scan"
};
_recognizedTextLabel = new Label();
_takenImage = new Image() { HeightRequest = 200 };
//버튼, 이미지, 인식결과텍스트 순서대로 배치
Content = new ScrollView
{
Content = new StackLayout
{
Children =
{
_takePictureButton,
_takenImage,
_recognizedTextLabel
}
}
};
}
private void WireEvents()
{
_takePictureButton.Clicked += TakePictureButton_Clicked;
}
async void TakePictureButton_Clicked(object sender, EventArgs e)
{
//버튼이 클릭되었을 때, Text 및 Enable 상태 변경
_takePictureButton.Text = "Working...";
_takePictureButton.IsEnabled = false;
//TesseractAPI 초기화 (언어 선정)
if (!_tesseractApi.Initialized)
await _tesseractApi.Init("eng");
//카메라 촬영 후 byte[] 형식 변수로 받아오기
var photo = await TakePic();
if (photo != null)
{
var imageBytes = new byte[photo.Source.Length];
photo.Source.Position = 0;
photo.Source.Read(imageBytes, 0, (int)photo.Source.Length);
photo.Source.Position = 0;
//문자 인식 수행
var tessResult = await _tesseractApi.SetImage(imageBytes);
//촬영이미지, 인식 결과 출력
if (tessResult)
{
_takenImage.Source = ImageSource.FromStream(() => photo.Source);
_recognizedTextLabel.Text = _tesseractApi.Text;
}
}
//버튼 상태 복구
_takePictureButton.Text = "New scan";
_takePictureButton.IsEnabled = true;
}
private async Task<MediaFile> TakePic()
{
var mediaStorageOptions = new CameraMediaStorageOptions
{
DefaultCamera = CameraDevice.Rear
};
var mediaFile = await _device.MediaPicker.TakePhotoAsync(mediaStorageOptions);
return mediaFile;
}
}
}
Init("eng"); 를 Init("kor"); 로 수정하면 인식 언어를 바꿀 수 있다.
다음은 결과 화면이다.
뉴스기사를 출력해서 인식해 보았다.
초기화면 |
|
|
카메라 촬영은 가로모드만 지원하고 세로로찍어도 가로로 돌아간 상태로 출력된다.
인식 성능은 속도가 상당히 나쁜편이다.
특히 사진이 부정확해서 인식이 어려울 때는 유난히 더 느리다.
개선할 방법을 공부해봐야겠다.
참고 사이트 : http://thatcsharpguy.com/post/tesseract-ocr-xamarin/
0 개의 댓글:
댓글 쓰기