windows

Windows10のOCR利用 画像より文字抽出 VB.NET

OCR読み取りは、C#で開発したOcrR.exeを使用。OCR読み取りの結果は、ファイル出力する。出力ファイルより読み取り結果をテキストBOXへ読み込みます。表示された画像から読み取り範囲を指定してOCR読み取りが可能。

Form1.vb

Imports System.Security.Cryptography

Public Class Form1

'画像用の座標
Private pos As Point

'Form1オブジェクトを保持するためのフィールド
Public Shared Form1Instance As Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

    Form1.Form1Instance = Me

End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    open()

End Sub

Private Sub open()

    'OpenFileDialogクラスのインスタンスを作成
    Dim ofd As New OpenFileDialog()
    'はじめのファイル名を指定する
    'はじめに「ファイル名」で表示される文字列を指定する
    ofd.FileName = "default.jpg"
    'はじめに表示されるフォルダを指定する
    '指定しない(空の文字列)の時は、現在のディレクトリが表示される
    ofd.InitialDirectory = System.Environment.CurrentDirectory
    '[ファイルの種類]に表示される選択肢を指定する
    '指定しないとすべてのファイルが表示される
    ofd.Filter = "jpeg-pngファイル(*.jpg;*.png)|*.jpgl;*.png|すべてのファイル(*.*)|*.*"
    '[ファイルの種類]ではじめに選択されるものを指定する
    '2番目の「すべてのファイル」が選択されているようにする
    ofd.FilterIndex = 2
    'タイトルを設定する
    ofd.Title = "開くファイルを選択してください"
    'ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
    ofd.RestoreDirectory = True
    '存在しないファイルの名前が指定されたとき警告を表示する
    'デフォルトでTrueなので指定する必要はない
    ofd.CheckFileExists = True
    '存在しないパスが指定されたとき警告を表示する
    'デフォルトでTrueなので指定する必要はない
    ofd.CheckPathExists = True

    'ダイアログを表示する
    If ofd.ShowDialog() = DialogResult.OK Then
        'OKボタンがクリックされたとき、選択されたファイル名を表示する
        Console.WriteLine(ofd.FileName)
        TextBox1.Text = ofd.FileName
        '画像ファイルを読み込んで、Imageオブジェクトを作成する
        Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(TextBox1.Text)

        '画像を表示する
        PictureBox1.Image = img

    End If

End Sub

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

    End

End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

    ocr()

End Sub

Private Sub ocr()

    Label3.Text = System.Environment.CurrentDirectory
    Dim Ret As Long
    Dim MyFile As String
    MyFile = Label3.Text & "\OcrR.exe" & " " & TextBox3.Text & " " & TextBox1.Text
    Ret = Shell(MyFile, vbNormalFocus, True, 60000)

    'Shift-JISコードとして開く
    Dim sr As New System.IO.StreamReader(Label3.Text & "\test.txt",
        System.Text.Encoding.GetEncoding("UTF-8"))
    '内容をすべて読み込む
    Dim s As String = sr.ReadToEnd()
    '閉じる
    sr.Close()
    TextBox2.Text = TextBox2.Text + vbCrLf + Replace(s, " ", "")

End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

    Dim img As Image = PictureBox1.Image
    pos.X = e.X * img.Width / PictureBox1.Width
    pos.Y = e.Y * img.Height / PictureBox1.Height
    TextBox4.Text = TextBox4.Text + Str(pos.X) + "," + Str(pos.Y) + ","

    Dim xy() = Split(TextBox4.Text, ",")
    If xy.Length > 4 Then

        TextBox5.Text = xy(xy.Length - 5)
        TextBox6.Text = xy(xy.Length - 4)
        TextBox7.Text = xy(xy.Length - 3)
        TextBox8.Text = xy(xy.Length - 2)

        TextBox4.Text = xy(xy.Length - 5) + ","
        TextBox4.Text += xy(xy.Length - 4) + ","
        TextBox4.Text += xy(xy.Length - 3) + ","
        TextBox4.Text += xy(xy.Length - 2) + ","

    End If

End Sub

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

    ocr_part()

End Sub

Private Sub ocr_part()

    '元画像
    Dim source As Bitmap
    source = New Bitmap(TextBox1.Text)

    '切り取るサイズ
    Dim x1 = Int(TextBox5.Text)
    Dim y1 = Int(TextBox6.Text)
    Dim x2 = Int(TextBox7.Text)
    Dim y2 = Int(TextBox8.Text)

    Dim rect As Rectangle
    rect = New Rectangle(x1, y1, x2 - x1, y2 - y1)

    '切り取り後の画像
    Dim trimed As Bitmap
    trimed = source.Clone(rect, source.PixelFormat)

    '保存
    trimed.Save("trimed.jpg")

    source.Dispose()
    trimed.Dispose()
    Label3.Text = System.Environment.CurrentDirectory
    Dim Ret As Long
    Dim MyFile As String
    MyFile = Label3.Text & "\OcrR.exe" & " " & TextBox3.Text & " " & Label3.Text & "\trimed.jpg"
    Ret = Shell(MyFile, vbNormalFocus, True, 60000)

    'Shift-JISコードとして開く
    Dim sr As New System.IO.StreamReader(Label3.Text & "\test.txt",
        System.Text.Encoding.GetEncoding("UTF-8"))
    '内容をすべて読み込む
    Dim s As String = sr.ReadToEnd()
    '閉じる
    sr.Close()
    TextBox2.Text = TextBox2.Text + vbCrLf + Replace(s, " ", "")

End Sub

Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click

    TextBox2.Text = ""

End Sub

Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click

    hozon()

End Sub

Private Sub hozon()

    'SaveFileDialogクラスのインスタンスを作成
    Dim sfd As New SaveFileDialog()

    'はじめのファイル名を指定する
    'はじめに「ファイル名」で表示される文字列を指定する
    sfd.FileName = "新しいファイル.txt"
    'はじめに表示されるフォルダを指定する
    '指定しない(空の文字列)の時は、現在のディレクトリが表示される
    sfd.InitialDirectory = System.Environment.CurrentDirectory
    '[ファイルの種類]に表示される選択肢を指定する
    sfd.Filter = "TEXTファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*"
    '[ファイルの種類]ではじめに選択されるものを指定する
    '2番目の「すべてのファイル」が選択されているようにする
    sfd.FilterIndex = 1
    'タイトルを設定する
    sfd.Title = "保存先のファイルを選択してください"
    'ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
    sfd.RestoreDirectory = True
    '既に存在するファイル名を指定したとき警告する
    'デフォルトでTrueなので指定する必要はない
    sfd.OverwritePrompt = True
    '存在しないパスが指定されたとき警告を表示する
    'デフォルトでTrueなので指定する必要はない
    sfd.CheckPathExists = True

    'ダイアログを表示する
    If sfd.ShowDialog() = DialogResult.OK Then
        'OKボタンがクリックされたとき、選択されたファイル名を表示する
        'Console.WriteLine(sfd.FileName)
        'Shift JISで書き込む
        '書き込むファイルが既に存在している場合は、上書きする
        Dim sw As New System.IO.StreamWriter(sfd.FileName,
            False,
            System.Text.Encoding.GetEncoding("UTF-8"))
        'TextBox1.Textの内容を書き込む
        sw.Write(TextBox2.Text)
        '閉じる
        sw.Close()
    End If

End Sub

Private Sub 選択ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 選択ToolStripMenuItem.Click
    open()

End Sub

Private Sub OCR全体処理ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OCR全体処理ToolStripMenuItem.Click
    ocr()

End Sub

Private Sub OCR選択処理ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OCR選択処理ToolStripMenuItem.Click
    ocr_part()

End Sub

Private Sub 消去ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 消去ToolStripMenuItem.Click
    TextBox2.Text = ""

End Sub

Private Sub 保存ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 保存ToolStripMenuItem.Click
    hozon()

End Sub

Private Sub 終了ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 終了ToolStripMenuItem.Click
    End

End Sub

Private Sub Label4_Click(sender As Object, e As EventArgs) Handles Label4.Click

    Form2.ShowDialog()

End Sub

画面選択ボタンを押下し。画像を選択します。マウスで読み取りする場所を始点(左上)と終点(右下)のBOXで指定します。OCR選択処理ボタンを押下。読み取り結果が、表示されます。保存ボタンでテキストファィルとして保存されます。読み取り結果は、テキストBOXへ追加されます。初期化する場合は、消去ボタンで初期化されます。OCR全体処理ボタンは、選択に関係なく全体をOCR読み取りします。言語は、既定 ja です。読み取り言語の言語環境を設定することで精度は向上します。

using NLog;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Media.Ocr;

namespace OcrR
{

    internal sealed class Program
    {
               
        private static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                return;
            }

            // Setup ocr engine
            var languageTag = args[0];
            if (!TrySetupOcrEngine(languageTag, out var ocrEngine))
                return;

            // Read image binary
            var path = args[1];
            var image = GetImageBinary(path);
            if (image == null)
                return;

            // Convert to SoftwareBitmap
            var bitmap = ConvertToSoftwareBitmap(image).Result;
            if (bitmap == null)
                return;

            // Run ocr and display result
            RunOcr(ocrEngine, bitmap);

        }

        
        private static async Task<SoftwareBitmap> ConvertToSoftwareBitmap(byte[] image)
        {
           
            try
            {
                using (var memoryStream = new MemoryStream(image))
                using (var randomAccessStream = memoryStream.AsRandomAccessStream())
                {
                    var decoder = await BitmapDecoder.CreateAsync(randomAccessStream);
                    return await decoder.GetSoftwareBitmapAsync();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to convert to SoftwareBitmap");
                return null;
            }
            finally
            {
                
            }
        }

        private static byte[] GetImageBinary(string path)
        {
            
            try
            {
                return File.ReadAllBytes(path);
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to get image file binary");
                return null;
            }
            finally
            {
                
            }
        }

        private static void RunOcr(OcrEngine ocrEngine, SoftwareBitmap bitmap)
        {
            
            try
            {
                var task = ocrEngine.RecognizeAsync(bitmap).AsTask();
                task.Wait();
                
                var text = task.Result.Text;
                File.WriteAllText(System.IO.Directory.GetCurrentDirectory() + @"\test.txt", text);
                Console.WriteLine(text);
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to run ocr");
            }
            finally
            {
               
            }
        }

        private static bool TrySetupOcrEngine(string languageTag, out OcrEngine engine)
        {
            engine = null;

            try
            {
                var language = new Windows.Globalization.Language(languageTag);

                // https://docs.microsoft.com/en-us/uwp/api/windows.media.ocr.ocrengine.trycreatefromlanguage?view=winrt-22621
                engine = OcrEngine.TryCreateFromLanguage(language);
                if (engine == null)
                {
                    Console.WriteLine("Failed to create ocr engine because it could be lack of language pack.");
                    return false;
                }

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to create ocr engine");
                return false;
            }
            finally
            {
                
            }

        }
    
      
    }

}

-windows

PAGE TOP