indico api를 사용한 콘텐츠 필터링된 이미지 업로더

개요



화제의 투고

요구사항


  • 로컬 화상을 판정해, OK였던 것만을 서버에 업로드한다.
  • 판정은 "3행의 소스 코드를 넣는 것만으로 기계 학습할 수 있다고 소문의 indico를 Node.js로 사용해 기계 학습 입문해 본다"의 Content Filetering API로 행한다.
  • 로컬에서 이미지 미리보기 기능을 제공합니다.

  • 실제 절차



    1. indico API 키 획득



    아래 사이트에서 계정을 만든 후 대시보드로 이동하여 API 키를 가져옵니다.
    indico

    2. 샘플 소스



    Docs의 페이지에서 Image Analysis ⇒ Content Filtering을 선택하고, javascript를 선택하면 API KEY까지 포함한 상태의 example 소스가 표시됩니다.

    example.
    // single example
    $.post(
      'https://apiv2.indico.io/contentfiltering',
      JSON.stringify({
        'api_key': "<API_KEY>",
        'data': "<IMAGE>"
      })
    ).then(function(res) { console.log(res) });
    
    // batch example
    $.post(
      'https://apiv2.indico.io/contentfiltering/batch',
      JSON.stringify({
        'api_key': "<API_KEY>",
        'data': [
          "<IMAGE>",
          "<IMAGE>"
        ]
      })
    ).then(function(res) { console.log(res) });
    

    3. <IMAGE> 정보



    는 이미지 파일의 URL 또는 Base 64로 인코딩된 이미지 데이터입니다. 이미지를 공개하지 않고 판정을 실시할 필요가 있으므로, FileReader()의 readAsDataURL() 메소드를 사용해 로컬 이미지 파일로부터 를 작성했습니다.

    4. 판정



    결과는 실수 0~1의 JSON 형식으로 리턴됩니다. 이런 느낌입니다.
    {"results": 0.2925722002983093}
    성인 콘텐츠로 간주될수록 숫자가 커지므로, 미리 설정한 스레시와 비교해 처리를 분기시키고 있습니다.

    소스 전체



    미리보기에는 canvas와 FileReader()를 사용하고 업로드는 FormData()를 AJAX로 POST하는 것으로 실시하고 있습니다. 서버 측 처리는 PHP입니다.

    index.html
    <!DOCTYPE HTML>
    <html lang="ja">
        <head>
            <meta charset="UTF-8">
            <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
            <title>画像ファイルをCANVSでプレビュー</title>
        </head>
        <body>
            <h1>画像を選択してください。</h1>
            <form id="my_form">
                <input id="ufile" name="ufile" type="file" accept="image/jpeg,image/png"><br>
                <button id="upload" type="button">アップロード</button>クリックでアップロードを開始します。
            </form>
            <hr>
            <div>
                <h1>プレビュー</h1>
                <canvas id="cnvs"></canvas>
            </div>
    
            <script>
             $(function(){
    
                 // Global変数
                 var fr = new FileReader(); // FileReader()をインスタンス化
                 var canvas = $("#cnvs");   // HTMLのCanvas要素の取得
                 var gheight = 240;         // Previewイメージの高さ
                 var thresh = 0.95;         // 判定基準値 さじ加減
    
                 // id="ufile"の変化でコールバック
                 $("#ufile").change(function(){
                     // 選択ファイルの有無をチェック
                     if (!this.files.length) {
                         alert('ファイルが選択されていません');
                         return;
                     }
    
                     // Formからファイルを取得
                     var file = this.files[0];
    
                     // getContext()メソッドで描画機能を有効にする
                     var ctx = canvas[0].getContext('2d');
    
                    // 描画イメージインスタンス化
                     var image = new Image();
    
                    // ファイル読み込み読み込み完了後に実行 [非同期処理]
                     fr.onload = function(evt) {
    
                         // 画像がロードされた後にcanvasに描画を行う [非同期処理]
                         image.onload = function() {
                             // プレビュー(Cnavas)のサイズを指定
                             var cnvsH = gheight;
                             var cnvsW = image.naturalWidth*cnvsH/image.naturalHeight;
                             // Cnavasにサイズアトリビュートを設定する
                             canvas.attr('width', cnvsW);
                             canvas.attr('height', cnvsH);
                             // 描画
                             ctx.drawImage(image, 0, 0, cnvsW, cnvsH);
                         }
                         // 読み込んだ画像をimageのソースに設定
                         image.src = evt.target.result; // == fr.result
                     }
    
                     // fileを読み込む データはBase64エンコードされる
                     fr.readAsDataURL(file);
                 })
    
                 $("#upload").click(function(){
                     if(!fr.result){
                         alert('ファイルを選択して下さい');
                         return;
                     };
    
                    $.post(
                         'https://apiv2.indico.io/contentfiltering',
                         JSON.stringify({
                             'api_key': "<API_KRY>",
                             'data': fr.result
                         })
                     ).then(function(res) {
                         var jst = JSON.parse(res);
                         if (jst.results > thresh) {
                             alert('この画像は規約によりアップロード出来ません rating='+jst.results);
                         } else {
                             console.log(res);
                             // FormDataを用意
                             var fd = new FormData($("#my_form").get(0));
                             // ajaxでphpに送信
                             $.ajax({
                                 url: 'uploader.php',
                                 type: 'POST',
                                 processData: false,
                                 contentType: false,
                                 dataType: 'html',
                                 data: fd
                             }).done(function(data, textStatus, jwXHR){
                                 alert(data);
                             }).fail(function(jqXHR, textStatus, errorThrown){
                                 alert('エラーが発生しました : ' + textStatus
                                       + "\nHTTP status : " + errorThrown);
                             })
                         }},
                         function() {
                             alert('エラーが発生しました。時間をおいて再試行下さい。');
                         })
                 })
             })
            </script>
        </body>
    </html>
    

    uploader.php
    <?php
    define('FILE_PATH','./upload/'); //保存するパスを指定
    
    // アップロードされたファイルが有る事を確認
    if (is_uploaded_file($_FILES["ufile"]["tmp_name"])) {
        $saveFilename = FILE_PATH . $_FILES['ufile']['name'];
    
        // ファイルの移動
        if (move_uploaded_file($_FILES["ufile"]["tmp_name"], $saveFilename)) {
            //chmod($saveFilename, 0644);
            echo $_FILES["ufile"]["name"], "をアップロードしました";
        } else {
            echo $_FILES["ufile"]["name"], "アップロードエラー";
        }
    }
    ?>
    

    결과 확인



    Firefox 47.0에서의 확인입니다.
    손상되지 않은 경우
    htps : // / ぢこ. 이오/

    OK인 경우

    좋은 웹페이지 즐겨찾기