AzureのFace APIで写真や画像から顔のパーツ・位置・推定年齢を取得

このエントリーをはてなブックマークに追加

写真や画像から目、鼻、口、眉毛のラインや位置を検出してみたい!ということで、Face APIを使い、JavaScriptで実装してみました。手順をメモしておきます。

1.Azureのページからアカウント登録して、APIキーを発行

https://azure.microsoft.com/

お試しで実施する分にはフリープランで大丈夫です。

APIキー、2つ発行されますが、どちらを使っても大丈夫みたいです。

2.ファイルを作成して試してみる

私の場合は、JavaScriptで作成しました。python、ruby、Java、Go、C#、色々あります。ドキュメントはこちら。クイックスタート:REST API を使用して画像内の顔を検出する

上記ページに丁寧なサンプルがありますが、私が友人に「こんなのできるみたいよ〜」と見せるために作ったコードを貼り付けておきます。

3.サンプル

ファイル構成:
file/
 L upload_files/(画像アップロード用フォルダ)
 L detectFaces.php

var subscriptionKey = "自分の API KEY";

の部分は先ほど取得したAPIキーの1,2どちらかを入力。

<!DOCTYPE html>
<html>
	<head>
		<title>Face</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
		<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
	</head>
	<style>
		input[type="file"] {
		   display: none;
		}
		label {
		   background: #ddd;
		   padding: 10px 30px;
		   display: inline-block;
		   position: relative;
		   font-size:14px;
		}
		label:hover {
		   background: #ccc;
		}
		label::after {
		   content: "選択されていません";
		   font-size: 12px;
		   height: 20px;
		   line-height: 20px;
		   position: absolute;
		   right: -140px;
		   top: calc(50% - 10px);
		}
		label.changed::after {
		   content: "";
		}
		.filename {
		   font-size: 12px;
		}	
	</style>

	<body>
		<div class="container mt-4">
			<?php
			
				$url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
				$url .= "/".basename(dirname($_SERVER['SCRIPT_NAME']))."/";			
				$updir = "upload_files";
				$tmp_file = @$_FILES['upfile']['tmp_name'];
				@list($file_name,$file_type) = explode(".",@$_FILES['upfile']['name']);
				$copy_file = date("Ymd-His") . "." . $file_type;
				if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) {
					if (move_uploaded_file($tmp_file,"$updir/$copy_file")) {
						$current_image = $url."upload_files/".$copy_file;
					} else {
						echo "ファイルをアップロード出来ませんでした。";
					}
				} 
			?>
		
			<form action="<?php echo $url;?>detectFaces.php" method="post" enctype="multipart/form-data">
				<div id="input-group" class="mb-3">
				  <input type="file" id="01" name="upfile"><label for="01" id="input-label">ファイルを選択してください</label>
				</div>		
				<input type="submit" value="アップロード" class="btn btn-info">
			</form>
	
			<script>
			$(function(){
			  $("input[type='file']").on('change',function(){
			     var file = $(this).prop('files')[0];
			     if(!($(".filename").length)){
			       $("#input-group").append('<span class="filename"></span>');
			     }
			     $("#input-label").addClass('changed');
			     $(".filename").html(file.name);
			   });
			 });
			</script>
	
	
			<?php if($current_image!=""){?>
			
				<hr>
			
				<script type="text/javascript">
				    function processImage() {
				        // Replace <Subscription Key> with your valid subscription key.
				        var subscriptionKey = "自分の API KEY";
				    
				        var uriBase =
				            "https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect";
				    
				        // Request parameters.
				        var params = {
				            "returnFaceId": "true",
				            "returnFaceLandmarks": "true",
				            "returnFaceAttributes":
				                "age,gender,headPose,smile,facialHair,glasses,emotion," +
				                "hair,makeup,occlusion,accessories,blur,exposure,noise"
				        };
				    
				        // Display the image.
				        var sourceImageUrl = document.getElementById("inputImage").value;
				        document.querySelector("#sourceImage").src = sourceImageUrl;
				    
				        // Perform the REST API call.
				        $.ajax({
				            url: uriBase + "?" + $.param(params),
				    
				            // Request headers.
				            beforeSend: function(xhrObj){
				                xhrObj.setRequestHeader("Content-Type","application/json");
				                xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
				            },
				    
				            type: "POST",
				    
				            // Request body.
				            data: '{"url": ' + '"' + sourceImageUrl + '"}',
				        })
				    
				        .done(function(data) {
				            // Show formatted JSON on webpage.
				            $("#responseTextArea").val(JSON.stringify(data, null, 2));
				        })
				    
				        .fail(function(jqXHR, textStatus, errorThrown) {
				            // Display error message.
				            var errorString = (errorThrown === "") ?
				                "Error. " : errorThrown + " (" + jqXHR.status + "): ";
				            errorString += (jqXHR.responseText === "") ?
				                "" : (jQuery.parseJSON(jqXHR.responseText).message) ?
				                    jQuery.parseJSON(jqXHR.responseText).message :
				                        jQuery.parseJSON(jqXHR.responseText).error.message;
				            alert(errorString);
				        });
				    };
				</script>
			
				<h1>Faces:</h1>
				<div class="small mb-4">
					<?php echo $current_image;?>
				</div>
				<div class="d-none">
					<input type="text" name="inputImage" id="inputImage" value="<?php echo $current_image;?>" />
					<button onclick="processImage()">Analyze face</button>
				</div>
				<div id="wrapper" class="row">
					<div class="col-12 col-lg-2">
					    <div id="imageDiv">
					        <div class="h5 py-2">Source image</div>
					        <img id="sourceImage" width="100%" />
					    </div>
					</div><!-- col -->
					<div class="col-12 col-lg-5">
					    <div id="jsonOutput">
					        <div class="h5 py-2">Response</div>
					        <textarea id="responseTextArea" class="UIInput small" style="width:100%;height:600px;"></textarea>
					    </div>
					</div><!-- col -->					
					<div class="col-12 col-lg-5">
					    <div id="jsonOutput">
					        <div class="h5 py-2">サンプルと値 <a href="https://docs.microsoft.com/ja-jp/azure/cognitive-services/face/images/landmarks.1.jpg" target="blank" class="small ml-2" rel="noopener noreferrer"><span class="small">→ faceLandmarksの値</span></a></div>
					        <textarea id="" class=" small" style="width:100%;height:600px;">[
faceRectangle:顔の座標
faceLandmarks:パーツの位置(リンク先参照)
faceAttributes:
	smile:笑顔
	headPose:顔の傾き
	gender:性別
	age:年齢
	facialHair:
		moustache:くち髭
		beard:あご髭
		sideburns:ほお髯
	glasses:眼鏡
	emotion:
	    anger:怒り
	    contempt:軽蔑
	    disgust:嫌悪
	    fear:恐れ
	    happiness:幸せ
	    neutral:通常
	    sadness:悲しみ
	    surprise:驚き	
	blur:ぼやけ
	exposure:露出
	noise:ノイズ
	makeup:化粧
	accessories:アクセサリー
	occlusion:顔を塞いでいるか
	hair:髪の毛
]</textarea>
					    </div>
					</div><!-- col -->	
				</div>
				
				<script>
					window.onload = function() {
					  processImage();
					};	
				</script>
			
			<?php } ?>
		</div><!-- container -->
	</body>
</html>

顔検出データについて

目、鼻、口、眉毛のラインや位置を検出できます。取得できるデータ詳細はこちらのページをご覧ください。
顔検出と顔属性

画像内の人間の顔の色々なデータを返すFace.api、面白いです。

木村 漠 baku kimura
Twitter facebook
個人事業(在庫管理システム開発)→ 起業/経営(Webマーケティング・開発/スクール)→メディアデザイン室長/新規事業開発/人事部長(クリエイティブ/社内システム/HR・採用)→取締役(開発〜お茶の買い出しまで色々)現在は外国人専門の求人サービスづくりを頑張っています。
携わってるサービス
外国人の求人・採用 job search in japan お笑い芸人を身近に!芸人キャスティング・ブッキング