Blogブログ

2023.04.01

【一撃実装】画像からテキスト検出|google cloud vision apiとphpでocr

こんちは。

FIELDの山本です。
今日はgoogleのCloud Vision APIで使って画像から文字を取得するというPHPプログラムを書いてみます。

はじめは「PHP 画像からテキスト」とかで検索してみました。
無料でできる!PHPで画像からテキストを読み取る方法
このあたりの記事をもとにゼロからやってみたのですが、、

見ての通り、精度がぜんっぜんだめ!!

本当に画像からテキストを抽出を考えている人で、
phpの無料ocrライブラリでやろうと思ってるなら
マジでやめたが方いいです。
スリランカの画像見せたのに「北海道です」と言われるくらいの精度で、
何も使えないです。

結論。やはり、googleのCloud Vision APIを使うしかない。

というわけで、
実務レベルで画像からテキストを抽出するPHPのAPI google Cloud Visionの使い方と実際に動くプログラムを紹介します。

もうめんどうだからdocker-compose up -dして終わりにしてさっさと画像からテキストをOCRで取得したい

だからさっさとコードとdockerだけ見せてくれという気持ち。
わかります。

でもそういうのがなかったので、
このブログを書いてるわけなのです。

一応調べてみたのですが、
一番初めにGoogleのOCRサイトがひっかかりました。
見た瞬間に、もう何書いてあるか5秒でわからなかったのでこの記事は生ごみだなとおもいそっと閉じました(本家なのに)。


次に「画像からテキストを検出する OCR サービス – Google Cloud Vision API」というブログを見つけたのですが、5秒だけ見て思ったことは
「なんか開発の前にGoogleCloudで登録みたいなことしないといかん」ってことですね。これはめんどくさそうなのでそっ閉じしました。

次にかの有名なクラスメソッドさんの記事を見つけました。
5秒見て思いました。
「なるほど、なんかgoogle coludでのOCR Google Cloud Vision APIの設定をするのは避けられないんだな。」


この情報だけで十分です。
覚悟が決まりました。
仕方ないから地道に見てやるか。。

前置きはここまでで、
このブログでは今から記載する方法で
そのままPHPでOCR Google Cloud Vision APIで画像からテキストが取得されます。

これからGoogleCloudの画面で色々設定していくのですが、
わたしは今静岡県の藤枝市というところにいまして、
ここは「朝ラー」という文化があり、
朝ラーメンを食べるということなのですが、
そのような文化を体験するためにわざわざ藤枝市まできました。
ここのラーメンを並びながら3日間に分けて書いていこうと思います。

1日目 ◯源に行きました。

朝4:45に行ったのにもう並んでいるので入れませんので、
今のうちに急いでGoogleCloudのコンソールのセットアップをします。

  1. ダッシュボードにアクセスしてください。 https://console.cloud.google.com/home/dashboard
  2. プロジェクトを作成します。

ここを押して、
で、、

今は、テストとしてOCRivoice2とかで登録をしてみますが
ここは自分でプロジェクト名を記載してください、

そしたらメニューのAPIサービスからライブラリをクリックし..

サービスの中でCloud VisionAPIを探して、
そして、

こいつを有効にします。

◯源のラーメンきました。おいしかったです。
まぁ普通でした。

2日目 まるみに行きました。

普通に朝7時に入れましたが、
お客さんが誰もいなく、なかなかラーメンも来ないので今のうちに作業をしていきます。

Googleクラウドの続きで、
支払いを有効にしましょう。
もともと支払いが有効になっていればいいのですが、
支払いが有効になっていないとAPIコールとbillingなんちゃらというエラーがでてストレスではげますのでそういう目に遭わないようにさきに支払いの設定をしましょう。(経験者は語る)

請求は各自しっかりと対応してください。
省略します。(このブログにも課金をしっかりすると書いてあるのでわたしと同じ苦しみを味わったかなと思いました。)

次に、Google Cloud Vision API (OCR)を有効にします。
そのやり方は…

まず、

有効にしたらキーを発行します。

JSON型でキーを作成し
ダウンロードします。
例としてこんな感じのキーがダウンロードできます。

{
  "type": "service_account",
  "project_id": "ocrinv24oice2",
  "private_key_id": "430esdf01d44eea1366a7fac175648f6f93d4fde9476b90",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBAdDANBgkqhkiG9w0BAQEFAsdfASCBKcwggSjAgEAAoasdIBAQCo35ofT77ta+asdfej\n35mMRM7uTZZAm+t2qVvCPwNtLvopuctzWSfvQ3cBxzO68/+bQt7ef1jyK+V6JeSdW\nESfbzkSvmu12d5wo5VAnmcQD6ifFNN773hmdhxQi63fl1izYV0Ac8yfoNI2wCp6fwr\nEa5cS5Ght65GgsSgDoF0iBqBIf7aCL6S1hO1gAqO/k0xRB9kebzdLY78OW5UHIuF\nK7VRJuz7QSep6TzRUXhVAr49j59lLofj6FPT+1ibxtLiOT5IkorrtD05y9K1yqTa\nLaWN+0HO6+wBWVo5EQY+fYG/a5buQ6cvPWn2v2GWq5j1c/KGcXZwu1niBpRRKsop\nvRIxcU0rAgMBAAECggEAREZ2+P7UWgg81HfkDB6LrTQoMcGLKkHRK8WUw/hq3oHJ\nAEhUK5tkIX5x7W7m4m7Mqi5DNwrgKmOVwEnaXBd2lKrjuEotIniIM2CUEjyCr6lk\nkzAQnqXb3msUFYyzTnYmz6rvqEaG66uCvOT+oikZXZE2QCLBnVaQB025rYjRkVO8\ncTy3dfVE3bkgHrabLX+Nxt47wegYLdNu1SAEkSaNcKuHSM3iITZGvS2q2eHciY0D\nkQJyekVIyT/gwLu+1VPsXJ2lMpNCrlEPGv9V0hyLos5rEYsMrU9NzMCc+F0Sa6rb\nFNSme+pHFbCCUBb5Io1otAy9EBPFDLVGTCzKJO1C+QKBgQDZb1esCfKRqkQRj34I\nDfmu4Yec8pCgJ3S4OORfq6J/MYUNDm2TMrPblDBspnF8PX0K3FxOWULFatOPURZs\nJh0kdgiWJIBdxtSBwcs73wV/FcOrtCR9qqGkE3EKJnOK7S6wbu+F0qW7iWng6zXt\neG1qoBEo603IY8gfBAUB9WqfQwKBgQDG01Hgl/xNggTu+5YaUAtDC6mNiS4e8Rmd\nLXqPDLUad/azyibs+ZJGW/C4BJFVgLXg5GDfYaHJk4p/bfGGxKav9Jm1PEF6iBir\nKObO533bbLprMKZ8PGN1vfvlMdmF4jhLTGuPH2bv4bI9Dk1etHnbnktZ9IGRwTMV\nuH98jJc3+QKBgQCaL3tjErbBFpUoQrGjco2QtnrdD6EBAJmjHSzMrsAPJAVuacHH\n9NdXqPDhyvGEoXGvJu4J3QAdUBBve5fD3w8hUNXr6jxgw2LkFJFShma2ZK+ZbafG\nuR3gZKzu/q9GX8SQ9knBgstlfh7nkMNv/srQJmuksZ85r5A0djw61FXkUwKBgCSg\nfz/Zn9ADeLcxv6gfQMPcHSMGt2lZzvcmjqJVm/NBUEA0qFEVdL3jaAfuR3ux10+T\nosjj6nMA7A2nikviZDab38kETaet9KVrRoGtIYFPmVPvxWuzkDr7gbDqKwE/+FDe\nxh26kjL0p+oZfWVJ5/zuP0FWCpx4M9n3f/zIxX65AoGAc08sVDZxgXq2jXtiaOTK\njynjyqPbeYVUn7KU9aJRE1np052J6XCs7MgwYtKsbcR1lblbmSnHmaSMKMs49rOj\nBwT3XeG9YrivMrLCiy/U0SgpBfG2jQyrcFDdwK/0HIWtU7OuV2appBiwLKQHgRQN\nU8ZrIJrraLWZuMV9zP5dHbY=\n-----END PRIVATE KEY-----\n",
  "client_email": "ocr2-495@osaddcrinvoice2.iam.gserviceaccount.com",
  "client_id": "10921313196433471211198330151",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/ocr2-495%40oc2ri3nvoice2.iam.gserviceaccount.com"
}

このようなjsonキーが手に入ったらOKです。
このキーやjsonファイルが流出すると大変なので適切に管理しましょう

キーをダウンロードしたら
appフォルダを作りindex.phpを作ったら、
docker-compose up -dを実行してください

docker-compose.ymlはこれです

php:
    image: php:7.2-apache
    volumes:
      - ./app:/var/www/html
    ports:
      - 8082:80
    command: >
      sh -c "docker-php-ext-install bcmath && apache2-foreground"

でdocker-compose up -dをして

docker exec -it xxxxxxxx /bin/bash
でログインをし、

apt-get update
apt-get install sudo 
apt-get update
apt-get install -y curl git unzip
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

を実行して必要なライブラリをインストールしていきます。
解説すると…

apt-get update:システムのパッケージリストを最新の状態に更新します。
apt-get install sudo:sudoコマンドをインストールします。sudoは、root権限で実行する必要のあるコマンドを、一般ユーザーが実行するためのコマンドです。
apt-get update:再びシステムのパッケージリストを最新の状態に更新します。
apt-get install -y curl git unzip:必要な依存関係のパッケージをインストールします。
curlはデータの転送に使用され、gitはソースコードのバージョン管理システムで、unzipはzipファイルを解凍するためのユーティリティです。
curl -sS https://getcomposer.org/installer | php — –install-dir=/usr/local/bin –filename=composer:Composerと呼ばれるPHPのパッケージ管理システムをインストールします。このコマンドは、getcomposer.orgからComposerのインストーラーをダウンロードして、そのインストーラーをphpコマンドで実行して、Composerをシステムにインストールします。
–install-dir=/usr/local/binは、Composerを/usr/local/binディレクトリにインストールすることを指定し、–filename=composerは、インストールされた実行可能ファイルの名前をcomposerに設定することを指定します。

まぁこういう解説は読み飛ばしてくれて良いです。

googleのocrのSDKをcomposerでインストールするために
composeをインストールしておきます。

そしたら

composer require google/cloud-vision

これを実行します。

composer require google/cloud-visionは、Google Cloud Vision APIのクライアントライブラリであるgoogle/cloud-visionをプロジェクトに追加するためのComposerコマンドです。
google/cloud-visionはPHPで書かれたGoogle Cloud Vision APIのクライアントライブラリであり、Google Cloud Vision APIを使用して画像から情報を抽出するための機能を提供します。例えば、画像内の顔の検出、ロゴの検出、ラベルの抽出、テキストの検出などができます。
composer require google/cloud-visionは、Google Cloud Vision APIのクライアントライブラリであるgoogle/cloud-visionをプロジェクトに追加するためのComposerコマンドです。
google/cloud-visionはPHPで書かれたGoogle Cloud Vision APIのクライアントライブラリであり、Google Cloud Vision APIを使用して画像から情報を抽出するための機能を提供します。例えば、画像内の顔の検出、ロゴの検出、ラベルの抽出、テキストの検出などができます。
composer requireコマンドは、composer.jsonファイルにライブラリの依存関係を記述し、Composerが自動的に依存関係を解決して必要なファイルをダウンロードすることで、プロジェクトにライブラリを追加するためのコマンドです。

とかそういうのはどうでもいいのですが、
まだちょっとインストールするものがあります。
ここでSDKのコマンドを実行するとpythonがないよだのgoogle-cloud-cliがないよだの色々まだ言われるので下記を実行してください

sudo apt-get install python
sudo apt-get install apt-transport-https ca-certificates gnupg
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
sudo apt-get update && sudo apt-get install google-cloud-cli

これで準備はできましたので、

gcloud init

を実行してください
そうすると、
このような画面になるはずです。

このようになんかリンク出てきます。

このようにめちゃながいURLがでてくるので
コピーしてブラウザに貼り付けると
googleのログインを求められるので
ログインをすると長いパスワードがもらえます。
そしたらそれをcode:のところに貼り付けます。

すると、
自分のGoogle Cloudのプロジェクトの一覧が表示され
何番のプロジェクトで使いますかと聞いてきますので、
今回は11なので11と入力します。

これでgoogleSDKのセットは終わりです。

まるみの海老塩ラーメンを食べました。おいしかったです。
まぁ普通に美味しいラーメンでした。

3日目 ルデッサンにきました。

めちゃめちゃ並んでいるので
椅子に座って速攻でOCRのコードを終わらせます。

先ほどダウンロードした キーのjsonファイルを index.phpと同じ場所に移動してください

そしてindex.phpのxxxxxをそのjsonの名前に変えてください

<?php

require_once 'vendor/autoload.php';

use Google\Cloud\Vision\V1\ImageAnnotatorClient;

putenv("GOOGLE_APPLICATION_CREDENTIALS=xxxxxxxxxxxxxxxxxx.json");

if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['submit'])) {
    $image_path = 'https://www.keihi.com/app/uploads/2019/11/24091750/a48fc8cb825e702b01d0c3453b8f0027-1024x584.png';

    $imageContent = file_get_contents($image_path);
    $image_Content = 'https://www.keihi.com/app/uploads/2019/11/24091750/a48fc8cb825e702b01d0c3453b8f0027-1024x584.png';

    $imageAnnotatorClient = new ImageAnnotatorClient();
    $response = $imageAnnotatorClient->textDetection($imageContent);
    $text = $response->getTextAnnotations();
    $fileRead = $text[0]->getDescription();
    $imageAnnotatorClient->close();
}

?>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Google OCR</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container mt-5">
        <div class="row mt-5">
            <div class="col-sm-8 mx-auto">
                <div class="jumbotron">
                    <h1 class="display-8">Read Text from Images</h1>
                    <hr class="my-4">
                </div>
            </div>
        </div>
        <div class="row col-sm-8 mx-auto">
            <div class="card mt-2">
                <div class="card-body">
                    <form action="" method="post" enctype="multipart/form-data">
                        <div class="form-group">
                            <label for="filechoose">Choose File</label>
                            <input type="file" name="file" class="form-control-file" id="filechoose">
                            <button class="btn btn-success mt-3" type="submit" name="submit">Upload</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <div class="row mt-5">
        <div class="col-sm-8 mx-auto">
            <div class="jumbotron">
                <p class="lead">
                    <?php if ($_POST) : ?>
                    <pre>
                        <?= $fileRead ?>
                    </pre>
                    <?php endif; ?>
                </p>
                <hr class="my-4">
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
</body>

</html>

いらないと思いますがPHP部分解説

 require_once: 指定したファイルを一度だけ読み込みます。ここでは、autoload.phpファイルを読み込んでいます。

use: 名前空間をインポートします。ここでは、Google\Cloud\Vision\V1\ImageAnnotatorClientクラスを使用するためにインポー

トしています。

putenv: 環境変数を設定します。ここでは、Google Cloudの認証情報を指定しています。

$_SERVER: サーバー情報を保持するスーパーグローバル変数です。ここでは、HTTPリクエストメソッドがPOSTであることを確認し

ています。

isset: 変数がセットされているかどうかを調べます。ここでは、フォームが送信されたときにsubmitがセットされているかどう>かを確認しています。

file_get_contents: 指定したURLの内容を文字列として取得します。ここでは、画像のURLから画像を読み込んでいます。

ImageAnnotatorClient: Vision APIのImageAnnotatorクラスを初期化します。

textDetection: 画像のテキストを検出します。

getTextAnnotations: OCRで検出されたテキストを取得します。

$text[0]->getDescription(): OCRで検出されたテキストを変数に格納します。

$imageAnnotatorClient->close(): ImageAnnotatorClientを閉じます。

そしてブラウザでアクセスすると・・・。

そして、領収書をアップしてみます。

すると。。

テキスト取れました。

ルデッサンめちゃめちゃうまいです。
6:45にならんでラーメンがきたのが8時でした。
これだけ時間があれば、はじめからこの店で全ての作業を終えることができたなと後悔しています。

ちなみにルデッサンはミシュラン三ツ星常連店である「カンテサンス」の岸田周三シェフがプライベートで訪れるという噂ですが、昔一緒にフレンチを修行していたようですね。そのときに焼津のサスエ前田魚店から仕入れていて、いまだにカンテサンスのシェフはサスエから仕入れているためにその帰りにルデッサンに寄るということらしいです。なんのブログでしたっけ。

ラーメンを食べながらIT系に転職したいという人はこちらから