LINEBOTで画像文字起こしと有害検出

動作

文字起こし

画像を送信したら文字にして返してくれる。

有害検出

特殊メイクの場合は暴力的に反応してます

仕組み

基本的にAPIの組み合わせで成り立ってます。

LINEのAPIはもちろん、画像解析用のCloudVisionAPIというGoogleのAPIを使用しています。

CloudVision:
https://cloud.google.com/vision/?hl=ja

ここからデモを試せますし、概要も書いてあります。

かんたんな話、送られてきた画像のバイナリをCloudVisionに送って、分析結果をJSONで返してもらうだけです。

LINEBOTをつかったオウム返し:
https://kazzstorage.com/linebot-trial/

文字起こし

APIKeyさえ用意できれば、あとはコメントみたらわかると思います。APIKeyは各自用意してください(CloudVisionAPIは登録時にクレカ情報が要ります)。

<?php
// APIKey
$line_api_token = "*************...";
$cloudvision_api_key = "*************...";

// メッセージデータ取得
$message_data = json_decode(file_get_contents("php://input"));

// 各種データ
$reply_token  = $message_data->{"events"}[0]->{"replyToken"};
$message_type = $message_data->{"events"}[0]->{"message"}->{"type"};
$message_id = $message_data->{"events"}[0]->{"message"}->{"id"};

// 画像以外が送られてきたら強制終了
if($message_type !== "image") exit();

// 送られてきた画像を取得
$ch = curl_init("https://api.line.me/v2/bot/message/{$message_id}/content");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json; charser=UTF-8",
    "Authorization: Bearer " . $line_api_token
]);
// 画像データをbase64にエンコードし取得
$image_data = base64_encode(curl_exec($ch));
curl_close($ch);

// cloudvisionあてのリクエスト組み立て
$cloudvision_req = json_encode([
    "requests" => [
        [
            "image" => [
                "content" => $image_data
            ],
            "features" => [
                [
                    "type" => "TEXT_DETECTION",
                    "maxResults" => 1
                ]
            ]
        ]
    ]
]);

// cloudvisionへ送信
$curl = curl_init() ;
curl_setopt($curl, CURLOPT_URL, "https://vision.googleapis.com/v1/images:annotate?key={$cloudvision_api_key}") ;
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $cloudvision_req);
$cloudvision_res = curl_exec($curl);
curl_close($curl);

// description(抽出した画像)を取得
$cloudvision_res_data = json_decode($cloudvision_res);
$description = $cloudvision_res_data->{"responses"}[0]->{"textAnnotations"}[0]->{"description"};

// 文字起こし文字列をテキストにセット
$res_message_data = json_encode([
    "replyToken" => $reply_token,
    "messages" => [
        [
            "type" => "text",
            "text" => $description
        ]
    ]
]);

// 返信
$ch = curl_init("https://api.line.me/v2/bot/message/reply");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $res_message_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json; charser=UTF-8",
    "Authorization: Bearer " . $line_api_token
]);
curl_exec($ch);
curl_close($ch);

有害レベル

5項目をそれぞれ5段階で返してくれます。特殊メイクは医療的と暴力的に反応してますね。google検索で拾ってきた画像なので、パクリにも反応してますね。

<?php
// APIKey
$line_api_token = "****************...";
$cloudvision_api_key = "****************...";

// メッセージデータ取得
$message_data = json_decode(file_get_contents("php://input"));

// 各種データ
$reply_token  = $message_data->{"events"}[0]->{"replyToken"};
$message_type = $message_data->{"events"}[0]->{"message"}->{"type"};
$message_id = $message_data->{"events"}[0]->{"message"}->{"id"};

// 画像以外が送られてきたら強制終了
if($message_type !== "image") exit();

// 送られてきた画像を取得
$ch = curl_init("https://api.line.me/v2/bot/message/{$message_id}/content");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json; charser=UTF-8",
    "Authorization: Bearer " . $line_api_token
]);
// 画像データをbase64にエンコードし取得
$image_data = base64_encode(curl_exec($ch));
curl_close($ch);

// cloudvisionあてのリクエスト組み立て
$cloudvision_req = json_encode([
    "requests" => [
        [
            "image" => [
                "content" => $image_data
            ],
            "features" => [
                [
                    "type" => "SAFE_SEARCH_DETECTION",
                    "maxResults" => 1
                ]
            ]
        ]
    ]
]);

// cloudvisionへ送信
$ch = curl_init() ;
curl_setopt($ch, CURLOPT_URL, "https://vision.googleapis.com/v1/images:annotate?key={$cloudvision_api_key}") ;
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_POSTFIELDS, $cloudvision_req);
$cloudvision_res = curl_exec($ch);
curl_close($ch);

// description(抽出した画像)を取得
$cloudvision_res_data = json_decode($cloudvision_res);
$safe_level["adult"] = $cloudvision_res_data->{"responses"}[0]->{"safeSearchAnnotation"}->{"adult"};
$safe_level["spoof"] = $cloudvision_res_data->{"responses"}[0]->{"safeSearchAnnotation"}->{"spoof"};
$safe_level["medical"] = $cloudvision_res_data->{"responses"}[0]->{"safeSearchAnnotation"}->{"medical"};
$safe_level["violence"] = $cloudvision_res_data->{"responses"}[0]->{"safeSearchAnnotation"}->{"violence"};
$safe_level["racy"] = $cloudvision_res_data->{"responses"}[0]->{"safeSearchAnnotation"}->{"racy"};

// 5段階評価を%変換
foreach($safe_level as $key => $val) {
    if($val === "VERY_LIKELY") {
        $safe_level[$key] = "100%";
    } else if($val === "LIKELY") {
        $safe_level[$key] = "75%";
    } else if($val === "POSSIBLE") {
        $safe_level[$key] = "50%";
    } else if($val === "UNLIKELY") {
        $safe_level[$key] = "25%";
    } else if($val === "VERY_UNLIKELY") {
        $safe_level[$key] = "0%";
    } else {
        $safe_level[$key] = "??%";
    }
}

// 返信メッセージ
$res_message  = "アダルト: " . $safe_level["adult"]    ."\n";
$res_message .= "パクリ: "   . $safe_level["spoof"]    ."\n";
$res_message .= "医療的: "   . $safe_level["medical"]  ."\n";
$res_message .= "暴力的: "   . $safe_level["violence"] ."\n";
$res_message .= "性的: "     . $safe_level["racy"];

// 文字起こし文字列をテキストにセット
$res_message_data = json_encode([
    "replyToken" => $reply_token,
    "messages" => [
        [
            "type" => "text",
            "text" => $res_message
        ]
    ]
]);

// 返信
$ch = curl_init("https://api.line.me/v2/bot/message/reply");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $res_message_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json; charser=UTF-8",
    "Authorization: Bearer " . $line_api_token
]);
curl_exec($ch);
curl_close($ch);

“type” => “SAFE_SEARCH_DETECTION”で有害検出モード

"features" => [
    [
        "type" => "SAFE_SEARCH_DETECTION",
        "maxResults" => 1
    ]
]

他にも

FACE_DETECTION顔検出
LANDMARK_DETECTION観光地検出
TEXT_DETECTION文字検出
LOGO_DETECTIONロゴ検出
SAFE_SEARCH_DETECTION有害検出
LABEL_DETECTIONカテゴリ検出
IMAGE_PROPERTIES色彩検出

その他

CloudVisionドキュメント:
https://cloud.google.com/vision/docs/?hl=ja

The present writer kazz.

関連記事

+socket.ioで簡易チャットアプリ作った
+自然言語処理のCOTOHA APIをPHPで使ってみた
+ブラウザで動くオンライン対戦リバーシ作ってみた
+LINEBOTを楽に実装できるPHPライブラリ作った
+ブラウザで遊べるリバーシを作る