LoginSignup
1
3

More than 3 years have passed since last update.

Dlibの顔認証と画像貼り付け

Posted at

Dlibを使った顔認証で、複数人の中から一人を選び顔貼り付けをしたいです

Pycharmでdlibを使って、webカメラを用いた顔検出を行なっています。(検出した顔の上に写真を貼り付けるプログラムになります。)
複数人の顔を認証し、全員に貼り付けするところまでできています。
どこを変えれば、特定の人物に貼り付けられるようになりますでしょうか?機械学習ではない方法で、何かあれば教えていてだきたいです。(貼り付けたい人物をクリックするとその人物にのみ貼り付けられるなど)
コードは下記の通りです。よろしくお願いします。

import cv2
import dlib
from datetime import datetime

IMAGE_PATH = "./niko.png"
CAPTURE_SCALE = 0.5

def main():

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

cap = cv2.VideoCapture(0)

while True:
    _, frame = cap.read()

    frame = img_resize(frame, CAPTURE_SCALE)
    h, w, _ = frame.shape

    img = frame
    dets = detector(frame[:, :, ::-1])

    if len(dets) > 0:
        parts = predictor(frame, dets[0]).parts()
        distance, pos = calc_distance_and_pos(img, parts)
        icon, icon_w, icon_h = load_icon(IMAGE_PATH, distance)

        if (pos != None) and (distance > 0.0):
            x = pos.x - int(icon_w / 2)
            y = pos.y - int(icon_h / 2)
            if (0 <= y) and (y <= (h - int(icon_h))) and (0 <= x) and (x <= (w - int(icon_w))):

                img = merge_images(img, icon, x, y)

    cv2.imshow("camera", img)

    if len(dets) > 0:
        for det in dets:
            parts = predictor(frame, det).parts()
            distance, pos = calc_distance_and_pos(img, parts)
            icon, icon_w, icon_h = load_icon(IMAGE_PATH, distance)

            #if (pos != None) and (distance > 0.0):
                #x = pos.x - int(icon_w / 2)
                #y = pos.y - int(icon_h / 2)
                #if (0 <= y) and (y <= (h - int(icon_h))) and (0 <= x) and (x <= (w - int(icon_w))):
                    #img = merge_images(img, icon, x, y)



    cv2.imshow("camera", img)

    k = cv2.waitKey(1) & 0xff
    if k == ord('q'):

        break
    elif k == ord('p'):

        save_image(img)
        cv2.imshow("saved", img)


cap.release()
cv2.destroyAllWindows()

def load_icon(path, distance):
icon = cv2.imread(path, -1)
icon_height, _ = icon.shape[:2]
icon = img_resize(icon, float(distance * 1.5 / icon_height))
icon_h, icon_w = icon.shape[:2]

return icon, icon_w, icon_h

def img_resize(img, scale):
h, w = img.shape[:2]
img = cv2.resize(img, (int(w * scale), int(h * scale)))
return img

def calc_distance_and_pos(img, parts):

cnt = 0
pos = None
p1 = None
distance = 0.0

for i in parts:
    if (cnt == 0):

        p1 = i
    if (cnt == 16):

        distance = ((p1.x - i.x) ** 2 + (p1.y - i.y) ** 2) ** 0.5
    if (cnt == 33):
        pos = i
    cv2.putText(img, str(cnt), (i.x, i.y), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 0, 255), thickness=1,
                lineType=cv2.LINE_8)
    cv2.circle(img, (i.x, i.y), 1, (255, 0, 0), -1)
    cnt = cnt + 1

return distance, pos

def save_image(img):
date = datetime.now().strftime("%Y%m%d_%H%M%S")
path = "./" + date + ".png"
cv2.imwrite(path, img)

def merge_images(bg, fg_alpha, s_x, s_y):
alpha = fg_alpha[:, :, 3]
alpha = cv2.cvtColor(alpha, cv2.COLOR_GRAY2BGR)
alpha = alpha / 255.0

fg = fg_alpha[:, :, :3]

f_h, f_w, _ = fg.shape
b_h, b_w, _ = bg.shape


print("f_w:{} f_h:{} b_w:{} b_h:{} s({}, {})".format(f_w, f_h, b_w, b_h, s_x, s_y))

bg[s_y:f_h + s_y, s_x:f_w + s_x] = (bg[s_y:f_h + s_y, s_x:f_w + s_x] * (1.0 - alpha)).astype(
    'uint8')
bg[s_y:f_h + s_y, s_x:f_w + s_x] = (bg[s_y:f_h + s_y, s_x:f_w + s_x] + (fg * alpha)).astype('uint8')

return bg

if name == 'main':
main()

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3