Office関連

Computer Vision APIを使って画像から文字列を取得するVBAマクロ

前々回の記事で、Fiddlerを使ってMicrosoft Cognitive ServicesのComputer Vision APIを呼び出してみましたが、今回はVBAマクロからAPIを呼び出してみようと思います。

VBAコード

さっそくコードです。
必要なエンドポイントURLやAPIキーは、前々回の記事を参考にして事前に取得しておいてください。

※ 下記コードはScriptControlを利用しているため、64ビット版Officeでは動作しません。

Option Explicit
 
Public Sub Sample()
  Debug.Print GetOCRTextUsingCognitiveServices("C:\Test\OCR.png")
End Sub
 
Private Function GetOCRTextUsingCognitiveServices(ByVal TargetFilePath As String, _
                                                  Optional ByVal TargetLanguage As String = "unk") As String
'CognitiveServices(Computer Vision API)を使って画像から文字列を取得
  Dim ret As String
  Dim js As String
  Dim url As String
  Dim dat As Variant
  
  Const apikey = "(APIキー)"
  Const adTypeBinary = 1
  Const adReadAll = -1
  url = "(エンドポイントURL)"
  If Right(url, 1) <> "/" Then url = url & "/"
  
  ret = "" '初期化
  
  'ファイル判定
  With CreateObject("Scripting.FileSystemObject")
    If .FileExists(TargetFilePath) = False Then GoTo Fin
    Select Case LCase(.GetExtensionName(TargetFilePath))
      Case "jpg", "jpeg", "png", "gif", "bmp"
      Case Else: GoTo Fin
    End Select
  End With
  
  'ファイル読込
  On Error Resume Next
  With CreateObject("ADODB.Stream")
    .Open
    .Type = adTypeBinary
    .LoadFromFile TargetFilePath
    dat = .Read(adReadAll)
    .Close
  End With
  If Err.Number <> 0 Then GoTo Fin
  On Error GoTo 0
  
  'Computer Vision API呼出
  With CreateObject("WinHttp.WinHttpRequest.5.1")
    .Open "POST", url & "v1.0/ocr?language=" & TargetLanguage, False
    .setRequestHeader "Ocp-Apim-Subscription-Key", apikey
    .setRequestHeader "Content-Type", "application/octet-stream"
    .send dat
    Select Case .Status
      Case 200: js = .responseText
      Case Else: GoTo Fin
    End Select
  End With
  If Len(Trim(js)) > 0 Then ret = GetTextFromJSON(js)
  
Fin:
  GetOCRTextUsingCognitiveServices = ret
End Function
 
Private Function GetTextFromJSON(ByVal js As String) As String
'JSONデータからテキスト取得
  Dim obj As Object
  Dim objRegions As Object
  Dim objRegion As Object
  Dim objLines As Object
  Dim objLine As Object
  Dim objWords As Object
  Dim objWord As Object
  Dim ret As String
  
  ret = "": js = "(" & js & ")" '初期化
  With CreateObject("ScriptControl")
    .Language = "JScript"
    Set obj = .Eval(js)
    Set objRegions = VBA.CallByName(obj, "regions", VbGet)
    For Each objRegion In objRegions
      If Not objRegion Is Nothing Then
        Set objLines = VBA.CallByName(objRegion, "lines", VbGet)
        For Each objLine In objLines
          Set objWords = VBA.CallByName(objLine, "words", VbGet)
          For Each objWord In objWords
            ret = ret & VBA.CallByName(objWord, "text", VbGet)
          Next
        Next
      End If
    Next
  End With
  GetTextFromJSON = ret
End Function

上記コードでは、GetOCRTextUsingCognitiveServicesプロシージャの第二引数で言語を指定できるようにしています。
標準の「unk」にしておけば自動判別されますが、意図した通りの言語で認識されない場合は、Cognitive Services APIs Referenceを参考に、言語を指定してください。

実行結果

上記マクロを実行した結果は、下記の通りでした。

日本における「夏(なっ)」の定義は、前述の中国暦の「A(xia)」の定義の強い影響を受けた上、近代においてクレコリオ暦に付随する欧米の文化的影響も受けて複雑な様相を呈している。中国暦以外の暦法を知らなかった前近代の時期には、中国暦の「A(xia)」の定義を日本人もそのまま受け人れさるを得なかった。しかし、海洋性気候てあり、肝心の夏至の時期には梅雨により日射が遮られる日本ては、前述の昼間の長さと気温のスレは中国より著しく大きくなる。日本列島においては、気温のヒ-クは立秋の時期にずれこむため、気温がヒ-クになる頃には、夏が糸冬わって秋が始まってしまっているという現象が生じることになる。このヰャップが、現在ても「暦の上では・・夏(秋)てすが・・・(気温の実感は全く違います)」というフレ-スが天気予報などて頻繁に用いられる原因となっている。

テストに使用したのが下記画像で、元の文はWikipediaから引っ張ってきたものです。

テキスト比較ツールで元の文と比較してみると、どこが認識できていないのかがよく分かります。

括弧や濁点の認識が上手くいっていませんが、ここまで認識できれば上出来です!
VBAから扱いづらいJSON形式のレスポンスが難点ですが、ScriptControlを使えば比較的簡単に処理できるでしょう。
アイデア次第で活用の場が広がると思うので、興味がある方は是非お試しください。

2017年8月の人気記事前のページ

スライドショーをループ再生設定するPowerPointマクロ次のページ

関連記事

  1. Office関連

    ちゃうちゃう! 2.0を操作するWordマクロ

    「テキスト比較ソフト「ちゃうちゃう!」がバージョンアップされました。」…

  2. Excel

    [VBA]DataObjectを使ったクリップボード操作が上手くいかない場合の対処法

    VBAマクロからクリップボードを操作する場合、定番となっているのがDa…

  3. Excel

    IEサポート終了でVBAマクロはどうなるの?

    ※下記情報は2021年5月時点の情報で、今後状況が変わっていく可能性が…

  4. Office関連

    Office 365 unified APIをVBAから呼び出す

    前回の記事で、VBAからOffice 365 APIを呼び出す手順につ…

  5. Office関連

    [VBA]ユーザーフォーム上のコンボボックスでオートコンプリート機能を実装する方法

    MSDNフォーラムに「ユーザーフォーム上のコンボボックスで、任意の文字…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP