顔の黄金比などを判定するのに使う比率を用いて
美人具合をランキングづけしてみました。
優勝者は誰でしょうか?
解説動画はこちら
さてやり方ですが
opencvを使って顔のポイントを取り
各パーツの長さを測ります。
そこから比率を出していきます。
顔のポイントを見るコードはこんな感じになります。
(要opencv,dlibのインストール)

顔は68ポイントの点を取ることができます。
今回のランキングは下記の方々10人の写真で行いました。
橋本環奈 さん
有村架純 さん
石原さとみ さん
新垣結衣 さん
広瀬すず さん
波瑠 さん
綾瀬はるか さん
浜辺美波 さん
桜井日奈子 さん
沢尻エリカ様
顔のパーツから比率を出すコードはこちら
顔のパーツの比率を出しまして
10人の平均を出しました。
その平均との乖離が一番少ない人が
美人だろうということでランキング付けしています。
結果は
ということで
意外な結果が出ました!!!
この10人の平均に一番近かったのは
この方

思いっきしファイル名間違えたのですが
各パーツの整い方が一番平均に近いということで
選ばれました。
今さらですが、このやり方だと
単純に平均に近いかどうかだけなので
美人かどうかの判断にはならないですよねーー
やはり各パーツの比率とかをもっと細かくとって
機械学習で絶対的な美人度を点数化する奴を
作らないとアレですよね。
絶対美人は誰なんだろうか
日本人全員にアンケートとってみたい!!
美人具合をランキングづけしてみました。
優勝者は誰でしょうか?
解説動画はこちら
さてやり方ですが
opencvを使って顔のポイントを取り
各パーツの長さを測ります。
そこから比率を出していきます。
顔のポイントを見るコードはこんな感じになります。
(要opencv,dlibのインストール)
import os
import time
import numpy as np
import cv2
import dlib
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches
%matplotlib inline
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("../shape_predictor_68_face_landmarks.dat")
image_path = 'img/hashikan.png'
image = cv2.imread(image_path, cv2.IMREAD_COLOR)
rects = detector(image, 1)
for rect in rects:
landmarks = np.matrix([[p.x, p.y] for p in predictor(image, rect).parts()])
fig, ax = plt.subplots(figsize=(16,9))
frame = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
for d in rects:
parts = predictor(frame, d).parts()
ax.scatter([point.x for point in parts], [point.y for point in parts])
for k, point in enumerate(parts):
ax.text(point.x, point.y, k)
ax.imshow(frame)
plt.tick_params(labelbottom=False,labelleft=False,labelright=False,labeltop=False)
plt.show()

顔は68ポイントの点を取ることができます。
今回のランキングは下記の方々10人の写真で行いました。
橋本環奈 さん
有村架純 さん
石原さとみ さん
新垣結衣 さん
広瀬すず さん
波瑠 さん
綾瀬はるか さん
浜辺美波 さん
桜井日奈子 さん
沢尻エリカ様
顔のパーツから比率を出すコードはこちら
def fwhrs(parts):
height = parts[8].y - parts[21].y
width = parts[16].x - parts[0].x
fwhr = width/height
return round(fwhr, 3)
def heights(parts):
top_height = parts[33].y - parts[21].y
bottom_height = parts[8].y - parts[33].y
return top_height,bottom_height
def widths(parts):
left_face = parts[16].x - parts[45].x
left_eye = parts[45].x - parts[42].x
middle_face = parts[42].x - parts[39].x
right_eye = parts[39].x - parts[36].x
right_face =parts[36].x - parts[0].x
return left_face, left_eye, middle_face, right_eye,right_face
def mouses(parts):
top_mouse = parts[57].y - parts[33].y
bottom_mouse = parts[8].y - parts[57].y
return top_mouse, bottom_mouse
df = pd.DataFrame()
for file_name in os.listdir('img'):
frame = cv2.imread('img/'+file_name)
dets = detector(frame[:, :, ::-1])
if len(dets) > 0:
parts = predictor(frame, dets[0]).parts()
fwhr = fwhrs(parts)
top_height,bottom_height = heights(parts)
left_face, left_eye, middle_face, right_eye,right_face = widths(parts)
top_mouse, bottom_mouse = mouses(parts)
t_dict = {'name':[file_name.replace('.png','')],
'fwhr':[fwhr],
'top_height':[top_height],
'bottom_height':[bottom_height],
'left_face':[left_face],
'left_eye':[left_eye],
'middle_face':[middle_face],
'right_eye':[right_eye],
'right_face':[right_face],
'top_mouse':[top_mouse],
'bottom_mouse':[bottom_mouse]}
tmp = pd.DataFrame(t_dict)
df = pd.concat([df,tmp])
df['Height-Ratio'] = df['top_height']/df['bottom_height']
df['Width-Ratio1'] = df['left_face']/df['middle_face']
df['Width-Ratio2'] = df['left_eye']/df['middle_face']
df['Width-Ratio3'] = df['right_eye']/df['middle_face']
df['Width-Ratio4'] = df['right_face']/df['middle_face']
df['Mouse-Ratio'] = df['top_mouse']/df['bottom_mouse']
ratios = ['Height-Ratio','Width-Ratio1','Width-Ratio2','Width-Ratio3','Width-Ratio4','Mouse-Ratio','fwhr']
df[ratios].mean()
difs = list(df[ratios].mean())
df['DIFF1'] = abs(difs[0] - df['Height-Ratio'] )
df['DIFF2'] = abs(difs[1]- df['Width-Ratio1'] )
df['DIFF3'] = abs(difs[2]- df['Width-Ratio2'] )
df['DIFF4'] = abs(difs[3]- df['Width-Ratio3'] )
df['DIFF5'] = abs(difs[4]- df['Width-Ratio4'] )
df['DIFF6'] = abs(difs[5]- df['Mouse-Ratio'] )
df['DIFF7'] = abs(difs[6] - df['fwhr'] )
df['total'] = df['DIFF1'] + df['DIFF2'] + df['DIFF3'] + df['DIFF4'] + df['DIFF5'] + df['DIFF6'] + df['DIFF7']
columns = ['name','total','fwhr','Height-Ratio','Width-Ratio1','Width-Ratio2','Width-Ratio3','Width-Ratio4','Mouse-Ratio']
df[columns].sort_values('total')
顔のパーツの比率を出しまして
10人の平均を出しました。
その平均との乖離が一番少ない人が
美人だろうということでランキング付けしています。
結果は
ということで
意外な結果が出ました!!!
この10人の平均に一番近かったのは
この方

思いっきしファイル名間違えたのですが
各パーツの整い方が一番平均に近いということで
選ばれました。
今さらですが、このやり方だと
単純に平均に近いかどうかだけなので
美人かどうかの判断にはならないですよねーー
やはり各パーツの比率とかをもっと細かくとって
機械学習で絶対的な美人度を点数化する奴を
作らないとアレですよね。
絶対美人は誰なんだろうか
日本人全員にアンケートとってみたい!!

コメント
コメント一覧 (2)
大学の研究において、顔の分析を行なっており、コードに関して質問させていただきたいのですが
後半部分のコードにおいて、最後の表作成はどのようにすれば良いのでしょうか?
ご連絡いただけると幸いです。
こちら、データは全てデータフレームに内包されるので
それをソートして表示すれば、表が表示されると思います
古いネタなのでコードが足りないかもしれないですが
データフレーム形式のデータを作成していただければ
すぐに表は表示が行えます
コメントする