経緯
個人的な趣味で、顔認識のAPIを使いたいなと思い立ちました。
OpenCVで自前でできないかなーとも思ったのですが、なかなか難しいっぽく、諦めてAPIを使うという選択になった次第です。
どこがAPIを提供しているのか、以下のリンクがとても参考になりました。
qiita.com
このリンクをもとに、それぞれ調べてみました。
調べる際の観点は「口の開閉が判別できるか」「その精度は確かか」という2点で調査をしました。
なお、調査したのは2017年の年末頃なので、この記事を書いている時点ですでに仕様が更新されている可能性があります。
目次
detectFace()
detectFace(); - 顔検出Webサービス → 2018.04.04にサービス提供終了になりました。
何より簡単に使えて、しかも無料というのがいい。
こんな感じのページ。

このAPIでは50個の特徴量を返してくれるみたいだ。

その結果、笑ってるか怒ってるかとかを判定したいと思ったらこっちで別途実装しなきゃいけないみたいだ。
それはそれで問題はないけども。
丁寧にサンプルページがあるので、実装する前に雰囲気確かめられる。
早速でもページから画像を投げてみる。
帰ってくるxmlはこんな感じ
<?xml version='1.0'?>
<faces>
<face id='0'>
<bounds x='328' y='550' width='100' height='100'/>
<right-eye x='365' y='591'/>
</face>
<face id='1'>
<bounds x='292' y='549' width='106' height='106'/>
</face>
<face id='2'>
<bounds x='706' y='256' width='709' height='709'/>
<right-eye x='907' y='538'/>
<left-eye x='1196' y='527'/>
<features s-avg='0.83' s-min='0.66' s-max='0.95'>
<point id='PR' x='921' y='536' s='0.80'/>
<point id='PL' x='1192' y='525' s='0.94'/>
<point id='BR2' x='1004' y='447' s='0.67'/>
<point id='BL2' x='1111' y='431' s='0.82'/>
<point id='N1' x='1057' y='531' s='0.78'/>
<point id='N5' x='1064' y='689' s='0.86'/>
<point id='M1' x='1068' y='796' s='0.85'/>
<point id='M5' x='1071' y='895' s='0.74'/>
<point id='M3' x='965' y='831' s='0.74'/>
<point id='M7' x='1176' y='830' s='0.82'/>
<point id='EL4' x='1257' y='534' s='0.93'/>
<point id='EL1' x='1139' y='545' s='0.92'/>
<point id='ER1' x='969' y='556' s='0.82'/>
<point id='ER4' x='871' y='538' s='0.84'/>
<point id='M2' x='1011' y='797' s='0.87'/>
<point id='M8' x='1109' y='793' s='0.91'/>
<point id='M4' x='1014' y='882' s='0.71'/>
<point id='M6' x='1145' y='872' s='0.75'/>
<point id='BR3' x='948' y='428' s='0.70'/>
<point id='BL3' x='1187' y='409' s='0.84'/>
<point id='N2' x='965' y='706' s='0.87'/>
<point id='N4' x='1149' y='703' s='0.92'/>
<point id='F1' x='1043' y='196' s='0.70'/>
<point id='F2' x='842' y='260' s='0.89'/>
<point id='F10' x='1252' y='286' s='0.69'/>
<point id='ER2' x='949' y='525' s='0.82'/>
<point id='ER3' x='891' y='522' s='0.81'/>
<point id='ER5' x='897' y='560' s='0.83'/>
<point id='ER6' x='936' y='567' s='0.81'/>
<point id='EL2' x='1164' y='508' s='0.92'/>
<point id='EL3' x='1231' y='508' s='0.93'/>
<point id='EL5' x='1229' y='547' s='0.94'/>
<point id='EL6' x='1170' y='551' s='0.92'/>
<point id='BR1' x='994' y='489' s='0.72'/>
<point id='BR4' x='890' y='436' s='0.79'/>
<point id='BR5' x='841' y='492' s='0.82'/>
<point id='BR6' x='919' y='449' s='0.77'/>
<point id='BL1' x='1111' y='468' s='0.81'/>
<point id='BL4' x='1240' y='414' s='0.83'/>
<point id='BL5' x='1298' y='450' s='0.90'/>
<point id='BL6' x='1226' y='437' s='0.85'/>
<point id='N3' x='1068' y='737' s='0.92'/>
<point id='M9' x='1068' y='834' s='0.83'/>
<point id='F3' x='779' y='558' s='0.87'/>
<point id='F9' x='1346' y='535' s='0.95'/>
<point id='F4' x='817' y='741' s='0.81'/>
<point id='F8' x='1323' y='720' s='0.90'/>
<point id='F6' x='1041' y='1041' s='0.66'/>
<point id='F5' x='849' y='880' s='0.78'/>
<point id='F7' x='1307' y='879' s='0.83'/>
</features>
</face>
</faces>
自分の使いたい用途に合わせるとしたら、どこか口以外の基準点から標準化するポイントを複数見つけておいて、画像のサイズを標準化してから、口の周りの特徴点の距離を調べるという方法だろうか。
AWS Rekognito
画像認識に関連したいろいろなサービスがある感じ。
これが人工知能というくくりのサービスなのはちょっと変な感じするが。

デモページもあった。

ただ、これを見ると、でもページの画像でさえ口開いてるのに閉じてるって判定されてたので(しかも信頼度72%)、精度はそこまで良くないのかもしれない。
試しに自分で取った写真をアップロードしてみても、ちょくちょく誤判定されてしまっている。
JSONも返してくれるが、特徴量が少ない気がする。特に口周り。
{
"FaceDetails": [
{
"BoundingBox": {
"Width": 0.2618750035762787,
"Height": 0.3930581510066986,
"Left": 0.14937500655651093,
"Top": 0.13414634764194489
},
"AgeRange": {
"Low": 26,
"High": 43
},
"Smile": {
"Value": true,
"Confidence": 99.0987319946289
},
"Eyeglasses": {
"Value": true,
"Confidence": 99.99999237060547
},
"Sunglasses": {
"Value": true,
"Confidence": 95.7325439453125
},
"Gender": {
"Value": "Female",
"Confidence": 100
},
"Beard": {
"Value": false,
"Confidence": 99.90460205078125
},
"Mustache": {
"Value": false,
"Confidence": 92.63785552978516
},
"EyesOpen": {
"Value": true,
"Confidence": 85.72091674804688
},
"MouthOpen": {
"Value": false,
"Confidence": 72.2423095703125
},
"Emotions": [
{
"Type": "HAPPY",
"Confidence": 99.69184112548828
},
{
"Type": "CALM",
"Confidence": 1.0618865489959717
},
{
"Type": "ANGRY",
"Confidence": 0.44966936111450195
}
],
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.2459116131067276,
"Y": 0.2963947355747223
},
{
"Type": "eyeRight",
"X": 0.32498690485954285,
"Y": 0.28320804238319397
},
{
"Type": "nose",
"X": 0.2972606122493744,
"Y": 0.338502436876297
},
{
"Type": "mouthLeft",
"X": 0.24349376559257507,
"Y": 0.43834927678108215
},
{
"Type": "mouthRight",
"X": 0.32762306928634644,
"Y": 0.4251043200492859
},
{
"Type": "leftPupil",
"X": 0.2514769434928894,
"Y": 0.2966562509536743
},
{
"Type": "rightPupil",
"X": 0.3339778780937195,
"Y": 0.28375154733657837
},
{
"Type": "leftEyeBrowLeft",
"X": 0.2145199030637741,
"Y": 0.2463952600955963
},
{
"Type": "leftEyeBrowUp",
"X": 0.2372017651796341,
"Y": 0.22838076949119568
},
{
"Type": "leftEyeBrowRight",
"X": 0.26641586422920227,
"Y": 0.2389357089996338
},
{
"Type": "rightEyeBrowLeft",
"X": 0.2992517352104187,
"Y": 0.23876728117465973
},
{
"Type": "rightEyeBrowUp",
"X": 0.3239707052707672,
"Y": 0.22483669221401215
},
{
"Type": "rightEyeBrowRight",
"X": 0.3491824269294739,
"Y": 0.23105363547801971
},
{
"Type": "leftEyeLeft",
"X": 0.22946621477603912,
"Y": 0.3019390404224396
},
{
"Type": "leftEyeRight",
"X": 0.2616650462150574,
"Y": 0.29498758912086487
},
{
"Type": "leftEyeUp",
"X": 0.24515913426876068,
"Y": 0.2873624563217163
},
{
"Type": "leftEyeDown",
"X": 0.24701011180877686,
"Y": 0.3033584654331207
},
{
"Type": "rightEyeLeft",
"X": 0.30755841732025146,
"Y": 0.2871529757976532
},
{
"Type": "rightEyeRight",
"X": 0.3417114317417145,
"Y": 0.2818377912044525
},
{
"Type": "rightEyeUp",
"X": 0.3245350122451782,
"Y": 0.27441540360450745
},
{
"Type": "rightEyeDown",
"X": 0.3257909119129181,
"Y": 0.2907133102416992
},
{
"Type": "noseLeft",
"X": 0.2787094712257385,
"Y": 0.38133224844932556
},
{
"Type": "noseRight",
"X": 0.308928519487381,
"Y": 0.37534570693969727
},
{
"Type": "mouthUp",
"X": 0.2901398241519928,
"Y": 0.4091244339942932
},
{
"Type": "mouthDown",
"X": 0.29399216175079346,
"Y": 0.4643388092517853
}
],
"Pose": {
"Roll": -8.045867919921875,
"Yaw": 17.916576385498047,
"Pitch": 13.156755447387695
},
"Quality": {
"Brightness": 40.16537857055664,
"Sharpness": 99.9980239868164
},
"Confidence": 99.82343292236328
}
]
}
Google Cloud Vision
顔認識もできるし、いろいろな情報も併せてくれる。
こんな感じでJSONを返してくれたりもするみたいだ。
dandaIMGL5048_TP_V.jpg
{
"faceAnnotations": [
{
"boundingPoly": {
"vertices": [
{
"x": 583,
"y": 49
},
{
"x": 1029,
"y": 49
},
{
"x": 1029,
"y": 567
},
{
"x": 583,
"y": 567
}
]
},
"fdBoundingPoly": {
"vertices": [
{
"x": 649,
"y": 161
},
{
"x": 975,
"y": 161
},
{
"x": 975,
"y": 487
},
{
"x": 649,
"y": 487
}
]
},
"landmarks": [
{
"type": "LEFT_EYE",
"position": {
"x": 719.5262,
"y": 253.72295,
"z": 0.000031506435
}
},
{
"type": "RIGHT_EYE",
"position": {
"x": 849.03937,
"y": 267.75647,
"z": -36.321598
}
},
{
"type": "LEFT_OF_LEFT_EYEBROW",
"position": {
"x": 686.8778,
"y": 221.65237,
"z": 27.712809
}
},
{
"type": "RIGHT_OF_LEFT_EYEBROW",
"position": {
"x": 754.03094,
"y": 225.36835,
"z": -30.87542
}
},
{
"type": "LEFT_OF_RIGHT_EYEBROW",
"position": {
"x": 816.0152,
"y": 231.25845,
"z": -48.467567
}
},
{
"type": "RIGHT_OF_RIGHT_EYEBROW",
"position": {
"x": 902.0392,
"y": 247.53323,
"z": -33.053932
}
},
{
"type": "MIDPOINT_BETWEEN_EYES",
"position": {
"x": 780.317,
"y": 254.34734,
"z": -45.376167
}
},
{
"type": "NOSE_TIP",
"position": {
"x": 760.82666,
"y": 325.50342,
"z": -93.64924
}
},
{
"type": "UPPER_LIP",
"position": {
"x": 758.0111,
"y": 379.47757,
"z": -70.47521
}
},
{
"type": "LOWER_LIP",
"position": {
"x": 750.76904,
"y": 417.12973,
"z": -67.296265
}
},
{
"type": "MOUTH_LEFT",
"position": {
"x": 709.657,
"y": 398.31903,
"z": -23.435837
}
},
{
"type": "MOUTH_RIGHT",
"position": {
"x": 818.4644,
"y": 414.50378,
"z": -52.383175
}
},
{
"type": "MOUTH_CENTER",
"position": {
"x": 756.7259,
"y": 397.63107,
"z": -63.729393
}
},
{
"type": "NOSE_BOTTOM_RIGHT",
"position": {
"x": 805.1426,
"y": 346.799,
"z": -55.52658
}
},
{
"type": "NOSE_BOTTOM_LEFT",
"position": {
"x": 733.29297,
"y": 340.7746,
"z": -35.59469
}
},
{
"type": "NOSE_BOTTOM_CENTER",
"position": {
"x": 763.22516,
"y": 350.47217,
"z": -67.04768
}
},
{
"type": "LEFT_EYE_TOP_BOUNDARY",
"position": {
"x": 721.1245,
"y": 244.94334,
"z": -8.15667
}
},
{
"type": "LEFT_EYE_RIGHT_CORNER",
"position": {
"x": 747.6377,
"y": 259.79794,
"z": -7.71021
}
},
{
"type": "LEFT_EYE_BOTTOM_BOUNDARY",
"position": {
"x": 718.8527,
"y": 263.2192,
"z": -2.942062
}
},
{
"type": "LEFT_EYE_LEFT_CORNER",
"position": {
"x": 699.73505,
"y": 254.79391,
"z": 18.149515
}
},
{
"type": "LEFT_EYE_PUPIL",
"position": {
"x": 719.1574,
"y": 254.79868,
"z": -3.427162
}
},
{
"type": "RIGHT_EYE_TOP_BOUNDARY",
"position": {
"x": 849.89404,
"y": 260.44193,
"z": -44.4995
}
},
{
"type": "RIGHT_EYE_RIGHT_CORNER",
"position": {
"x": 883.94965,
"y": 276.54755,
"z": -32.000946
}
},
{
"type": "RIGHT_EYE_BOTTOM_BOUNDARY",
"position": {
"x": 849.20135,
"y": 277.8363,
"z": -39.35131
}
},
{
"type": "RIGHT_EYE_LEFT_CORNER",
"position": {
"x": 823.90643,
"y": 269.1588,
"z": -29.444563
}
},
{
"type": "RIGHT_EYE_PUPIL",
"position": {
"x": 851.3009,
"y": 270.67163,
"z": -40.867477
}
},
{
"type": "LEFT_EYEBROW_UPPER_MIDPOINT",
"position": {
"x": 720.2593,
"y": 205.07675,
"z": -7.762258
}
},
{
"type": "RIGHT_EYEBROW_UPPER_MIDPOINT",
"position": {
"x": 859.88257,
"y": 221.919,
"z": -47.19713
}
},
{
"type": "LEFT_EAR_TRAGION",
"position": {
"x": 670.9434,
"y": 339.6975,
"z": 171.91898
}
},
{
"type": "RIGHT_EAR_TRAGION",
"position": {
"x": 963.58167,
"y": 374.80206,
"z": 89.242195
}
},
{
"type": "FOREHEAD_GLABELLA",
"position": {
"x": 783.9658,
"y": 224.99454,
"z": -44.277527
}
},
{
"type": "CHIN_GNATHION",
"position": {
"x": 748.6527,
"y": 486.20532,
"z": -57.60541
}
},
{
"type": "CHIN_LEFT_GONION",
"position": {
"x": 658.22473,
"y": 415.8591,
"z": 103.73505
}
},
{
"type": "CHIN_RIGHT_GONION",
"position": {
"x": 922.45325,
"y": 447.898,
"z": 29.103714
}
}
],
"rollAngle": 9.122541,
"panAngle": -15.808093,
"tiltAngle": 7.937726,
"detectionConfidence": 0.8733366,
"landmarkingConfidence": 0.5498749,
"joyLikelihood": "VERY_UNLIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
}
],
"labelAnnotations": [
{
"mid": "/m/01xyhv",
"description": "suit",
"score": 0.855479
},
{
"mid": "/m/01qkbx",
"description": "professional",
"score": 0.84650135
},
{
"mid": "/m/0n5szg6",
"description": "business executive",
"score": 0.81015223
},
{
"mid": "/m/012t_z",
"description": "businessperson",
"score": 0.7535335
},
{
"mid": "/m/01kq3x",
"description": "white collar worker",
"score": 0.67039
},
{
"mid": "/m/0289fz",
"description": "executive officer",
"score": 0.6614492
},
{
"mid": "/m/09x_r",
"description": "entrepreneur",
"score": 0.638664
},
{
"mid": "/m/09s1f",
"description": "business",
"score": 0.5803496
},
{
"mid": "/m/05s9tm",
"description": "talent manager",
"score": 0.51430815
},
{
"mid": "/m/019p5q",
"description": "gentleman",
"score": 0.50934017
}
],
"safeSearchAnnotation": {
"adult": "VERY_UNLIKELY",
"spoof": "VERY_UNLIKELY",
"medical": "VERY_UNLIKELY",
"violence": "VERY_UNLIKELY"
},
"imagePropertiesAnnotation": {
"dominantColors": {
"colors": [
{
"color": {
"red": 230,
"green": 230,
"blue": 237
},
"score": 0.5333071,
"pixelFraction": 0.5140667
},
{
"color": {
"red": 26,
"green": 26,
"blue": 28
},
"score": 0.21879509,
"pixelFraction": 0.26526666
},
{
"color": {
"red": 205,
"green": 203,
"blue": 213
},
"score": 0.1390053,
"pixelFraction": 0.11186667
},
{
"color": {
"red": 45,
"green": 43,
"blue": 47
},
"score": 0.029963521,
"pixelFraction": 0.0282
},
{
"color": {
"red": 225,
"green": 190,
"blue": 189
},
"score": 0.01627379,
"pixelFraction": 0.012933333
},
{
"color": {
"red": 164,
"green": 159,
"blue": 165
},
"score": 0.014597795,
"pixelFraction": 0.0132
},
{
"color": {
"red": 226,
"green": 183,
"blue": 174
},
"score": 0.007874987,
"pixelFraction": 0.014666666
},
{
"color": {
"red": 123,
"green": 118,
"blue": 121
},
"score": 0.0060422462,
"pixelFraction": 0.0058
},
{
"color": {
"red": 246,
"green": 214,
"blue": 214
},
"score": 0.005779971,
"pixelFraction": 0.0045333332
},
{
"color": {
"red": 86,
"green": 83,
"blue": 85
},
"score": 0.005673399,
"pixelFraction": 0.0055333334
}
]
}
},
"cropHintsAnnotation": {
"cropHints": [
{
"boundingPoly": {
"vertices": [
{
"x": 351
},
{
"x": 1215
},
{
"x": 1215,
"y": 1065
},
{
"x": 351,
"y": 1065
}
]
},
"confidence": 1,
"importanceFraction": 0.95
},
{
"boundingPoly": {
"vertices": [
{
"x": 255
},
{
"x": 1343
},
{
"x": 1343,
"y": 1065
},
{
"x": 255,
"y": 1065
}
]
},
"confidence": 1,
"importanceFraction": 0.98999995
},
{
"boundingPoly": {
"vertices": [
{
"x": 127
},
{
"x": 1423
},
{
"x": 1423,
"y": 1065
},
{
"x": 127,
"y": 1065
}
]
},
"confidence": 1,
"importanceFraction": 0.98999995
}
]
},
"webDetection": {
"webEntities": [
{
"entityId": "/g/12bprj7th",
"score": 1.1322
},
{
"entityId": "/g/1tgwpw14",
"score": 1.0244
},
{
"entityId": "/m/09s1f",
"score": 0.7011,
"description": "Business"
},
{
"entityId": "/m/01m2bt",
"score": 0.6569,
"description": "Venture capital"
},
{
"entityId": "/m/03bxgrp",
"score": 0.6054,
"description": "Company"
},
{
"entityId": "/m/018s5w",
"score": 0.5943,
"description": "Capital"
},
{
"entityId": "/m/02_7t",
"score": 0.5428,
"description": "Finance"
},
{
"entityId": "/g/1203l_bt9",
"score": 0.5194
},
{
"entityId": "/m/02nwq",
"score": 0.5148,
"description": "Entrepreneurship"
},
{
"entityId": "/m/03m3ym9",
"score": 0.5101,
"description": "Angel investor"
},
{
"entityId": "/m/023k2",
"score": 0.4496,
"description": "Corporation"
},
{
"entityId": "/m/03jzl9",
"score": 0.4287,
"description": "Share"
},
{
"entityId": "/m/0dlrgy",
"score": 0.4206,
"description": "All China Lawyers Association"
},
{
"entityId": "/m/0h3z7",
"score": 0.4193,
"description": "Initial public offering"
},
{
"entityId": "/m/0lbmv",
"score": 0.20668001,
"description": "Shenzhen"
}
],
"fullMatchingImages": [
{
"url": "http://timscholten.com/wp-content/uploads/2017/05/TimScholten-5.jpg"
},
{
"url": "https://www.pakutaso.com/shared/img/thumb/dandaIMGL5048.jpg"
},
{
"url": "http://stat.profile.ameba.jp/profile_images/20130317/19/1e/9f/j/o180025201363516460689.jpg"
},
{
"url": "http://www.gdszlvshi.com/UploadFiles/201662015263786.jpg"
},
{
"url": "https://www.pakutaso.com/shared/img/thumb/dandaIMGL5048_TP_V.jpg"
},
{
"url": "https://image.jimcdn.com/app/cms/image/transf/none/path/s4684c34cfcc8a80d/image/i400bb0104d9c3726/version/1454214695/image.jpg"
},
{
"url": "http://felvidek.ma/wp-content/uploads/2017/10/Becse-Norbert-fot%C3%B3-MKP.jpg"
},
{
"url": "http://www.wscom.com.br/arqs/arquivos/arquivos/201303081003240000008330.jpg"
},
{
"url": "http://upload-images.jianshu.io/upload_images/2548788-875d2c3997d23c47.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"
},
{
"url": "https://www.pakutaso.com/shared/img/thumb/dandaIMGL5048_TP_V4.jpg"
},
{
"url": "http://www.prachachat.net/online/2016/10/14775681281477568341l.jpg"
},
{
"url": "http://www.yemacaijing.com/kindeditor/attached/image/20160212/20160212155959_73709.jpg"
},
{
"url": "https://www.pakutaso.com/shared/img/thumb/dandaIMGL5048_TP_V1.jpg"
},
{
"url": "http://stat.profile.ameba.jp/profile_images/20160930/02/f3/Ot/j/o045204531475169331139.jpg"
},
{
"url": "https://image.jimcdn.com/app/cms/image/transf/dimension=210x1024:format=jpg/path/s4684c34cfcc8a80d/image/i400bb0104d9c3726/version/1454214695/image.jpg"
},
{
"url": "http://happymakeproject.com/wp-content/uploads/2016/02/image.jpg"
},
{
"url": "https://media.licdn.com/mpr/mpr/shrinknp_200_200/AAEAAQAAAAAAAATyAAAAJDEyMmM3MWY3LTQwZmYtNGI1Yi05ZjA1LTIxNzJhOGM1NjU4Ng.jpg"
},
{
"url": "https://media.licdn.com/mpr/mpr/shrinknp_200_200/AAEAAQAAAAAAAA3VAAAAJGY0ZThlMDg3LTdlMTYtNDAxMC05NzZhLTJiYWRmNjA5OTM0Yw.jpg"
},
{
"url": "http://img2.cyzone.cn/uploadfile/2015/0710/fa4005041f412e73d576693097584382.jpg"
},
{
"url": "https://media.licdn.com/mpr/mpr/shrink_100_100/AAEAAQAAAAAAAAxMAAAAJDliODg1ZWJmLTM5OTctNDk1Yi1iMTg0LTc5MWQ4YjAxZGQ3Yw.jpg"
}
],
"partialMatchingImages": [
{
"url": "https://www.pakutaso.com/shared/img/thumb/dandaIMGL5048_TP_V2.jpg"
}
],
"pagesWithMatchingImages": [
{
"url": "https://www.linkedin.com/in/andrewbwillis"
},
{
"url": "http://timscholten.com/media-sheet/images/"
},
{
"url": "https://sg.linkedin.com/in/amy-aw-1804433a"
},
{
"url": "https://holaconnect.com/profile/margaux-lefort-email-phone-93fee623"
},
{
"url": "http://felvidek.ma/2017/10/becse-norbert-mindent-megtesz-a-komaromi-jaras-fellenditese-erdekeben/"
},
{
"url": "http://www.yemacaijing.com/index/view/id/84.html"
},
{
"url": "http://www.yemacaijing.com/Index/view/id/84.html"
},
{
"url": "http://www.wscom.com.br/noticias/economia/JOAO+PESSOA+GANHA+CONCESSIONARIA+AUDI+-145150"
},
{
"url": "https://www.pakutaso.com/person/"
},
{
"url": "http://www.cyzone.cn/d/20150601/470.html"
},
{
"url": "http://happymakeproject.com/8678/"
},
{
"url": "https://dandashokai.com/8667"
},
{
"url": "http://www.cyzone.cn/f/20150710/1664.html"
},
{
"url": "https://www.prachachat.net/news_detail.php?newsid=1477568128"
},
{
"url": "https://www.pakutaso.com/person/man/"
},
{
"url": "http://www.jianshu.com/p/3580429d0a50"
},
{
"url": "http://m.prachachat.net/news_detail.php?newsid=1477568128"
},
{
"url": "http://profile.ameba.jp/dramamaster/"
},
{
"url": "http://profile.ameba.jp/panicgekitai"
},
{
"url": "http://www.gdszlvshi.com/showteam_1.html"
},
{
"url": "http://www.gdszlvshi.com/team.html"
},
{
"url": "https://panickaiketsu.jimdo.com/%E4%B8%89%E6%9C%A8%E3%83%92%E3%83%AD%E3%82%B7%E3%81%AE%E3%83%97%E3%83%AD%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB/"
},
{
"url": "http://hyperacy.site/%E0%B9%82%E0%B8%A1%E0%B8%A1%E0%B8%B9%E0%B8%AB%E0%B8%B0-%E0%B8%A3%E0%B8%B2%E0%B8%84%E0%B8%B2/"
},
{
"url": "http://www.10800.com/investor/details/id/14309"
},
{
"url": "https://holaconnect.com/profile/maman-bureau-email-phone-acf2ca62"
}
],
"visuallySimilarImages": [
{
"url": "http://www.realestateforachangingworld.co.uk/wp-content/uploads/2017/10/andy_martin-500x500.jpg"
},
{
"url": "https://www.irep.co.jp/global/wp-content/uploads/2016/03/Samuel3-e1485150192823.png"
},
{
"url": "http://www.bu.ac.th/wp-content/uploads/2016/07/%E0%B8%84%E0%B8%B8%E0%B8%93%E0%B8%A8%E0%B8%B8%E0%B8%A0%E0%B8%8A%E0%B8%B1%E0%B8%A2.jpg"
},
{
"url": "https://ireward.superghs.com/resource/htoo/page/Mr-Manish-Gupta.jpg"
},
{
"url": "http://www.recruit-rgf.com/csr/img/csr_common_president01.jpg"
},
{
"url": "https://www.capitalfirst.com/front-end/img/board-members/bm2.jpg"
},
{
"url": "https://www.dialog.lk/dialogdocroot/content/images/pr/supun.jpg"
},
{
"url": "https://lookaside.fbsbx.com/lookaside/crawler/media/?media_id=1116763798456374"
},
{
"url": "https://8iholdings.com/wp-content/uploads/2017/02/Profile-Joshua-440x440.jpg"
}
]
}
}
返ってくるJSONはこんな感じらしい。
Response:
[
{
"faceAttributes": {
"accessories": [],
"age": 22.9,
"blur": {
"blurLevel": "low",
"value": 0.06
},
"emotion": {
"anger": 0.0,
"contempt": 0.0,
"disgust": 0.0,
"fear": 0.0,
"happiness": 0.0,
"neutral": 0.986,
"sadness": 0.009,
"surprise": 0.005
},
"exposure": {
"exposureLevel": "goodExposure",
"value": 0.67
},
"facialHair": {
"beard": 0.0,
"moustache": 0.0,
"sideburns": 0.0
},
"gender": "female",
"glasses": "NoGlasses",
"hair": {
"bald": 0.0,
"hairColor": [
{
"color": "brown",
"confidence": 1.0
},
{
"color": "black",
"confidence": 0.87
},
{
"color": "other",
"confidence": 0.51
},
{
"color": "blond",
"confidence": 0.08
},
{
"color": "red",
"confidence": 0.08
},
{
"color": "gray",
"confidence": 0.02
}
],
"invisible": false
},
"headPose": {
"pitch": 0.0,
"roll": 0.1,
"yaw": -32.9
},
"makeup": {
"eyeMakeup": true,
"lipMakeup": true
},
"noise": {
"noiseLevel": "low",
"value": 0.0
},
"occlusion": {
"eyeOccluded": false,
"foreheadOccluded": false,
"mouthOccluded": false
},
"smile": 0.0
},
"faceId": "49d55c17-e018-4a42-ba7b-8cbbdfae7c6f",
"faceRectangle": {
"height": 162,
"left": 177,
"top": 131,
"width": 162
}
}
]
あまり詳細な表情の情報は渡してくれないみたいだ。
もうこっちがやっとくから、君たちは結果だけ見てればいいの。感が強い。ヤダ。
Face++
Face Landmark SDK - Face++ Cognitive Services
なんと顔の特徴料が106個あると。
しかも無料だと。
なんやかんやこれが一番良さそうだ。
ただ、使ってみるまでがちょっと面倒くさいです。
まずアカウントを登録して(メールが届くのが5分くらいかかった!)、携帯電話番号とかも登録しなくちゃAPIKeyが取得できません。
これで使い物にならなかったら腹立ちますね。
中国のサービスなので、電話番号とか悪用されないかなと心配してたのですが、この会社割りと有名な会社だったみたいですね。恥ずかしい。
中国の顔認証スタートアップFace++が2500万米ドルを調達、Jack Ma(馬雲)氏も顔認証決済を導入へ - THE BRIDGE(ザ・ブリッジ)
{
"image_id": "5XkklHlGoc1WTKaw25w5ww==",
"request_id": "1511624338,e08986b0-891b-46fb-9b1a-2c77a83dccbb",
"time_used": 427,
"faces": [
{
"landmark": {
"mouth_upper_lip_left_contour2": {
"y": 384,
"x": 719
},
"mouth_upper_lip_left_contour3": {
"y": 396,
"x": 728
},
"mouth_lower_lip_right_contour3": {
"y": 415,
"x": 772
},
"mouth_upper_lip_left_contour1": {
"y": 372,
"x": 743
},
"left_eye_upper_left_quarter": {
"y": 248,
"x": 706
},
"left_eyebrow_lower_middle": {
"y": 220,
"x": 716
},
"contour_chin": {
"y": 511,
"x": 750
},
"left_eyebrow_lower_left_quarter": {
"y": 219,
"x": 699
},
"right_eyebrow_lower_left_quarter": {
"y": 235,
"x": 832
},
"mouth_lower_lip_right_contour1": {
"y": 402,
"x": 783
},
"mouth_lower_lip_left_contour2": {
"y": 408,
"x": 717
},
"left_eye_bottom": {
"y": 260,
"x": 717
},
"mouth_lower_lip_bottom": {
"y": 412,
"x": 753
},
"contour_left9": {
"y": 497,
"x": 717
},
"mouth_lower_lip_top": {
"y": 394,
"x": 755
},
"right_eyebrow_upper_middle": {
"y": 217,
"x": 859
},
"right_eyebrow_left_corner": {
"y": 232,
"x": 806
},
"right_eye_bottom": {
"y": 279,
"x": 849
},
"contour_left7": {
"y": 448,
"x": 680
},
"contour_left6": {
"y": 416,
"x": 673
},
"contour_left5": {
"y": 382,
"x": 671
},
"contour_left4": {
"y": 349,
"x": 671
},
"contour_left3": {
"y": 317,
"x": 672
},
"contour_left2": {
"y": 287,
"x": 677
},
"contour_left1": {
"y": 257,
"x": 684
},
"left_eye_lower_left_quarter": {
"y": 258,
"x": 705
},
"mouth_upper_lip_top": {
"y": 376,
"x": 757
},
"contour_right3": {
"y": 371,
"x": 992
},
"contour_right2": {
"y": 328,
"x": 997
},
"mouth_left_corner": {
"y": 405,
"x": 701
},
"contour_right4": {
"y": 414,
"x": 982
},
"contour_right7": {
"y": 504,
"x": 893
},
"left_eyebrow_left_corner": {
"y": 219,
"x": 683
},
"nose_right": {
"y": 346,
"x": 814
},
"right_eye_upper_right_quarter": {
"y": 266,
"x": 867
},
"nose_tip": {
"y": 321,
"x": 757
},
"contour_right5": {
"y": 453,
"x": 963
},
"nose_contour_lower_middle": {
"y": 354,
"x": 762
},
"right_eye_top": {
"y": 261,
"x": 850
},
"mouth_lower_lip_left_contour3": {
"y": 410,
"x": 735
},
"right_eye_right_corner": {
"y": 275,
"x": 881
},
"right_eye_lower_right_quarter": {
"y": 278,
"x": 866
},
"mouth_upper_lip_right_contour2": {
"y": 393,
"x": 794
},
"right_eyebrow_lower_right_quarter": {
"y": 239,
"x": 883
},
"left_eye_left_corner": {
"y": 253,
"x": 695
},
"mouth_right_corner": {
"y": 417,
"x": 811
},
"mouth_upper_lip_right_contour3": {
"y": 402,
"x": 784
},
"right_eye_lower_left_quarter": {
"y": 276,
"x": 834
},
"left_eyebrow_right_corner": {
"y": 224,
"x": 752
},
"left_eyebrow_lower_right_quarter": {
"y": 223,
"x": 734
},
"right_eye_center": {
"y": 272,
"x": 850
},
"left_eye_upper_right_quarter": {
"y": 251,
"x": 731
},
"mouth_lower_lip_left_contour1": {
"y": 396,
"x": 728
},
"contour_left8": {
"y": 475,
"x": 695
},
"nose_left": {
"y": 336,
"x": 726
},
"right_eyebrow_lower_middle": {
"y": 236,
"x": 858
},
"left_eye_top": {
"y": 247,
"x": 718
},
"left_eye_center": {
"y": 255,
"x": 718
},
"left_eye_lower_right_quarter": {
"y": 260,
"x": 729
},
"nose_contour_right1": {
"y": 269,
"x": 805
},
"contour_right9": {
"y": 516,
"x": 798
},
"right_eye_left_corner": {
"y": 272,
"x": 819
},
"left_eyebrow_upper_left_quarter": {
"y": 207,
"x": 698
},
"left_eye_pupil": {
"y": 253,
"x": 718
},
"right_eyebrow_upper_left_quarter": {
"y": 219,
"x": 831
},
"contour_right8": {
"y": 514,
"x": 846
},
"right_eyebrow_right_corner": {
"y": 243,
"x": 906
},
"right_eye_upper_left_quarter": {
"y": 264,
"x": 833
},
"left_eyebrow_upper_middle": {
"y": 206,
"x": 718
},
"right_eyebrow_upper_right_quarter": {
"y": 223,
"x": 886
},
"nose_contour_left1": {
"y": 265,
"x": 758
},
"nose_contour_left2": {
"y": 312,
"x": 738
},
"mouth_upper_lip_right_contour1": {
"y": 375,
"x": 771
},
"contour_right1": {
"y": 285,
"x": 999
},
"nose_contour_right2": {
"y": 320,
"x": 806
},
"mouth_lower_lip_right_contour2": {
"y": 417,
"x": 792
},
"contour_right6": {
"y": 484,
"x": 933
},
"nose_contour_right3": {
"y": 352,
"x": 788
},
"nose_contour_left3": {
"y": 346,
"x": 742
},
"left_eye_right_corner": {
"y": 258,
"x": 740
},
"left_eyebrow_upper_right_quarter": {
"y": 211,
"x": 737
},
"right_eye_pupil": {
"y": 269,
"x": 849
},
"mouth_upper_lip_bottom": {
"y": 395,
"x": 755
}
},
"attributes": {
"emotion": {
"sadness": 0.044,
"neutral": 31.453,
"disgust": 21.391,
"anger": 47.017,
"surprise": 0.032,
"fear": 0.032,
"happiness": 0.032
},
"gender": {
"value": "Male"
},
"age": {
"value": 37
},
"eyestatus": {
"left_eye_status": {
"normal_glass_eye_open": 1.785,
"no_glass_eye_close": 0,
"occlusion": 0.355,
"no_glass_eye_open": 97.712,
"normal_glass_eye_close": 0.003,
"dark_glasses": 0.145
},
"right_eye_status": {
"normal_glass_eye_open": 0.004,
"no_glass_eye_close": 0,
"occlusion": 0.005,
"no_glass_eye_open": 99.991,
"normal_glass_eye_close": 0,
"dark_glasses": 0
}
},
"glass": {
"value": "None"
},
"headpose": {
"yaw_angle": 22.35016,
"pitch_angle": -8.229241,
"roll_angle": 9.0831785
},
"blur": {
"blurness": {
"threshold": 50,
"value": 0.378
},
"motionblur": {
"threshold": 50,
"value": 0.378
},
"gaussianblur": {
"threshold": 50,
"value": 0.378
}
},
"smile": {
"threshold": 30.1,
"value": 3.299
},
"facequality": {
"threshold": 70.1,
"value": 6.392
},
"ethnicity": {
"value": "Asian"
}
},
"face_rectangle": {
"width": 316,
"top": 201,
"left": 657,
"height": 316
},
"face_token": "06ae41e4d9d9fe3f614ea82bfbdeb289"
}
]
まずはDetect APIで顔を検出してから、その顔のIDを渡すことでAnalyze APIが使えるようです。
デモページはこんな感じ

Sweetheart(恋人)かどうか判定できるってのはすごいな〜
男女二人組を恋人なのかどうか見分けられるってすごいな〜
でも特徴量とかはくれないみたいだ。
JSONはこんな感じ。
結果とスコアしかくれない。
{
"classes": [
{
"class": "person",
"score": 0.851
},
{
"class": "sweetheart",
"score": 0.581,
"type_hierarchy": "/person/sweetheart"
},
{
"class": "people",
"score": 0.597,
"type_hierarchy": "/person/people"
},
{
"class": "couple",
"score": 0.518,
"type_hierarchy": "/person/couple"
},
{
"class": "woman",
"score": 0.556,
"type_hierarchy": "/person/female/woman"
},
{
"class": "female",
"score": 0.5
},
{
"class": "Indian red color",
"score": 0.988
}
],
"classifier_id": "default",
"name": "default"
}
結論
結論は、Face++を使ってみることにしました。
理由としては、特徴量が一番多く、精度も高そうだったためです。
(と、まとめるにあたってもう一度見渡してみたら、無料だしdetectFaceでも良かったのではないかな…と思っています。
と思って改めて見てみたら2018/0404にサービス終了していました。そういえば、これを採用しなかった理由は、提供元があまり聞いたことない会社だったのとで、いつサービス終了するかわからなかったのと、http通信なので、自分の顔写真を送るのには抵抗があったからでした。あの時の自分は正しかった!)
あとGoogle Cloud APIも悪くなかったと思うのですが、若干Face++よりもお高かったので、お見送りになりました。
次回は実際にFace++を用いて自己満サービスを作りたいと思います。