C#/C# 리니지m/
C#으로 만드는 리니지m 매크로 (2-1)hp인식 - tesseract
2019. 10. 2.
tesseract 설치와 기본사용법은 링크 참조
2019/10/01 - [프로그래밍/C# 프로그래밍] - C# tesseract 설치
2019/10/01 - [프로그래밍/C# 프로그래밍] - C# tesseract를 이용한 OCR
지난 시간 프로젝트에 이어서 하겠습니다.
조그마한 picturebox 1개
label 2개
button 2개를 추가해줍니다.
using문 추가해주고
using Tesseract;
버튼2 클릭 이벤트
private void Button2_Click(object sender, EventArgs e)
{
Rectangle rect = new Rectangle(130, 13, 85, 20);
// x,y 시작좌표 x,y범위 생성
Bitmap cap = screen.Clone(rect, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// 캡쳐뜬 이미지에서 위의 Rect 만큼 자르기
cap = new Bitmap(cap, new Size(170, 40));
// 인식률을 높이기위해 두배크기로 리사이즈
for(int i = 0; i < cap.Width; i++)
{
for(int j = 0; j < cap.Height; j++)
{
Color c = cap.GetPixel(i, j);
int binary = (c.R + c.G + c.B) / 3;
if (binary > 190)
cap.SetPixel(i, j, Color.White);
else
cap.SetPixel(i, j, Color.Black);
}
}
// 간단한 for을 통한 Binary(이진화)
screen = cap;
pictureBox2.Image = screen;
// picturebox2 에 자르고 키우고 이진화한 이미지 띄우기
}
주석 설명처럼 전체 이미지에서 hp숫자 부분만 캡처 후
인식률을 높이기위한 전처리 소스입니다.
버튼3 클릭 이벤트
private void Button3_Click(object sender, EventArgs e)
{
Pix pix = PixConverter.ToPix(screen);
var engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.TesseractOnly);
// tesseractengine 생성
string whitelist = "0123456789/";
engine.SetVariable("tessedit_char_whitelist", whitelist);
// 인식률을 높이기위한 숫자와 '/' 만 화이트리스트 적용
var result = engine.Process(pix);
string HP = result.GetText();
HP = HP.Replace(" ", "");
// 공백제거
label1.Text = HP;
string[] split = HP.Split('/');
// 현재와 맥스수치를 나눠주기 구분점 '/'
label2.Text = "HP : " + (Convert.ToSingle(split[0]) * 100 / Convert.ToSingle(split[1])).ToString("##.##") + "%";
}
버튼2에서 새로만든 이미지를 통해
tesseract를 이용하여 숫자인식
더불어 %로 표기하기위한 소스입니다.
이제 디버깅후 테스트 해봅시다.
실행후 앱플레이어명을 적은후
버튼1 클릭
지난 시간에 했던것 처럼 잘 캡처 되었네요
이제 버튼2 클릭
hp부분만 캡처자르기되어 이진화까지 잘된것을 볼 수 있습니다.
이제 버튼3 클릭
화면에 보이는 hp와 동일한 숫자가 인식되었고 %계산도 잘되었네요.
tesseract의 장점은 상용화 되어있어서 편하게 접할 수 있다 지만
단점으로는 전처리를 아무리해도 오인식하는 경우가 생기기도 합니다.
또 생각보다 컴퓨터 리소스를 많이 잡아먹는다는점
후에 하겠지만 반복으로 돌리면 리소스가 치솟는걸 보게됩니다
하여 정확하진않지만 픽셀서치로 근사% 구하는법 을 다음시간에 알려드리겠습니다.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Tesseract;
namespace imagesearch
{
public partial class Form1 : Form
{
[DllImport("User32", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr hWnd1, int hWnd2, string lp1, string lp2);
[DllImport("user32.dll")]
internal static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcblt, int nFlags);
Bitmap screen;
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
string a = textBox1.Text;
IntPtr b = FindWindow(null, a);
IntPtr c = FindWindowEx(b, 0, "RenderWindow", "TheRender");
Graphics gdata = Graphics.FromHwnd(c);
Rectangle rect = Rectangle.Round(gdata.VisibleClipBounds);
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
IntPtr hdc = g.GetHdc();
PrintWindow(c, hdc, 0x2);
g.ReleaseHdc(hdc);
}
screen = new Bitmap(bmp, new Size(1280, 720));
pictureBox1.Image = screen;
}
private void Button2_Click(object sender, EventArgs e)
{
Rectangle rect = new Rectangle(130, 13, 85, 20);
// x,y 시작좌표 x,y범위 생성
Bitmap cap = screen.Clone(rect, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// 캡쳐뜬 이미지에서 위의 Rect 만큼 자르기
cap = new Bitmap(cap, new Size(170, 40));
// 인식률을 높이기위해 두배크기로 리사이즈
for(int i = 0; i < cap.Width; i++)
{
for(int j = 0; j < cap.Height; j++)
{
Color c = cap.GetPixel(i, j);
int binary = (c.R + c.G + c.B) / 3;
if (binary > 190)
cap.SetPixel(i, j, Color.White);
else
cap.SetPixel(i, j, Color.Black);
}
}
// 간단한 for을 통한 Binary(이진화)
screen = cap;
pictureBox2.Image = screen;
// picturebox2 에 자르고 키우고 이진화한 이미지 띄우기
}
private void Button3_Click(object sender, EventArgs e)
{
Pix pix = PixConverter.ToPix(screen);
var engine = new TesseractEngine(@"./tessdata", "eng", EngineMode.TesseractOnly);
// tesseractengine 생성
string whitelist = "0123456789/";
engine.SetVariable("tessedit_char_whitelist", whitelist);
// 인식률을 높이기위한 숫자와 '/' 만 화이트리스트 적용
var result = engine.Process(pix);
string HP = result.GetText();
HP = HP.Replace(" ", "");
// 공백제거
label1.Text = HP;
string[] split = HP.Split('/');
// 현재와 맥스수치를 나눠주기 구분점 '/'
label2.Text = "HP : " + (Convert.ToSingle(split[0]) * 100 / Convert.ToSingle(split[1])).ToString("##.##") + "%";
}
}
}