ãã£ã¼ãã©ã¼ãã³ã°ã§ããæ¾ããã®å ã¤åã¯è¦åããããã®ãï¼ããæºåç·¨ã
æè¿ããæ¾ããã¨ããã¢ãã¡ãæµè¡ã£ã¦ãã¾ããã ï¼ã¤åã®ããæ¾ããã®ã¢ãã¡ãç¾ä»£çã«ã¢ã¬ã³ã¸ããä½åãªã®ã§ããããã®éç¨ã§ããããã®å å¼ã®ç¹å¾´ãä»ãããã¦ãã¾ãã
å·¦ãããããæ¾ãããæ¾ããã§ãæ¾ãä¸æ¾ãååæ¾ãã¨ã©æ¾ã§ãé ã«é·ç·æ¬¡ç·ä¸ç·ã»ã»ã»ã¨ãªã£ã¦ãã¾ãã
ç°¡åã«ã¾ã¨ããã¨ããã®ããã«ãªãã¾ãã
çã¾ã | åå | è² | ç¹å¾´ |
---|---|---|---|
é·ç· | ããæ¾ | 赤 | ã¯ãº |
æ¬¡ç· | ããæ¾ | é | ãã«ã·ã¹ã |
ä¸ç· | ãã§ãæ¾ | ç· | ããã³ããæèé«ãç³» |
åç· | ä¸æ¾ | ç´« | ã³ãã¥é |
äºç· | ååæ¾ | é»è² | ãã¤ãã¼ã¹ |
å ç· | ã¨ã©æ¾ | ãã³ã¯ | çãä¸æãè ¹é» |
ããããã®è²ãçã¦ããã¨ãã¯ãç°¡åã«è¦åãããã¾ãããããã§ãªãã¨ãã¯è¦åããã®ã«å°é£ãä¼´ãã¾ãã 髪ãç®ã¤ãã«ãç¹å¾´ãããã®ã§ãè¦åãããã¨ãã§ããã®ã§ããã®ãããªè¡¨ãä½ã£ã¦ãã£ãããæ¹ããã¾ãã
ããã§ãçµæ§è¦å´ããã®ã§ãåãããã£ã¼ãã©ã¼ãã³ã°ã§å¦ç¿ãããã¢ãã«ã§å¤å¥ã§ããªããã試ãã¦ã¿ã¾ããã ä»åã¯ãã®æºåç·¨ã§ãã
å¦ç¿ãã¼ã¿ã®ä½æ
ã¾ããã£ã¼ãã©ã¼ãã³ã°ã§ããæ¾ããã®é¡ãå¦ç¿ãããããã«ã¯ãã©ããªã³ã°ããã大éã®é¡ç»åãå¿ è¦ã«ãªãã¾ãã ã¢ãã¡é¡å¤å¥ã®å 人ããã§ã«ããã£ã£ããããã©ãã©ã¤ãã®äººã¯6000æãã注æã¯Deep Learningã§ããï¼ã®äººã¯12000æåéããã¨ã®ãã¨ãªã®ã§ãæ°åæãªã¼ãã¼ã®ç»åã¯å¿ è¦ã ã¨å¤æãã¾ããã
ç»ååéã®æ¹é
å 人ãã¡ã¯ãã¢ãã¡ã®ã¹ã¯ãªã¼ã³ã·ã§ããããé¡ã®é¨åã ãæ½åºãã¦ãæåã§ã©ããªã³ã°ããã¦ããã®ã§ãåæ§ã®ææ³ã§è¡ããã¨èããã¾ãããã以åããã¯ãç»åã®ã©ããªã³ã°ä½æ¥ã®çµé¨ããé£ããããããªããã¨èãã¾ããã
以åããã¯ãã®ã¡ã³ãã¼ã§ããããããã¨ãã¦ãç»åãã¹ã¯ã¬ã¤ãã³ã°ã»ã¹ã¯ãã¼ã«ãã¦åéãé¡ãåãæãã¦é ã«ã©ããªã³ã°ãã¦ãã£ãã®ã§ãããé¡ã ãã§ã©ããªã³ã°ããã®ã¯å¹çãè¯ãããã¾ããã§ãããæ®æ®µããã¯ãã¯å¤èåã¡ããã ã£ãã赤ããã«ã¡ããã ã£ããç´«ã¨ããããã«ãããããã®ã¡ã³ãã¼ã®è²ãã¾ã¨ã£ã¦ãããã¨ãå¤ããæ³å以ä¸ã«è²ã®æ å ±ã§åã ãå¤æãã¦ãããã¨ãã¾ãï¼å¹´éåã®åçãåå¨ãããããæé·éç¨ã§é¡ã®å½¢ãå¤ãã£ãããç©ããã太ã£ããã§ããªããªãå¹çãä¸ããã¾ããã§ããã
ããæ¾ããã®å ´åãåããããªãã¨ãèãããã¾ããã¿ãã§ããä¼¼ã¦ããã®ã«ãé¡ã ãåãæãã¦ã©ããªã³ã°ããã®ã¯å¹çãæªãã¨å¤æãã¾ããã ããã§ãã¢ãã¡ã«ãããåå¾ã®æèãæè£ ãä½ç½®ãªã©ã®æ å ±ã¨ã¨ãã«ã©ããªã³ã°ã§ããããã以ä¸ã®æ¹æ³ãèãã¾ããã
1, ã¢ãã¡ãæµããªãããå
¨ä½ã®ã¹ã¯ãªã¼ã³ã·ã§ãããæ®ã
2, æå®ãã£ã¬ã¯ããªã«ä¿åãããããã«å
¥ã£ãåçã«å¯¾ãã¦èªåã§é¡ãåãæãã¦ãããããã«ãã
3, åãæãããé¡åçããã¹ã¯ãããã§ãã©ã«ãåããã¦ãã
åãæãã«ã¤ãã¦ããOpenCV+AnimeFaceç·¨ã
å§ãã¯ãã©ãã©ã¤ãã®äººã使ã£ã¦ããOpenCV+AnimeFaceãå ã«ãæ¯ç§æå®ãã©ã«ããç£è¦ãåçãã¡ã¤ã«ãå ¥ã£ããé¡ãåãæãã¦å¥ãã©ã«ãã«å ¥ããããã«èãã¾ããã 以ä¸æ¸ããã½ã¼ã¹
#!/usr/bin/env python # -*- coding: UTF-8 -*- # # crop face from all picture in specific directory in every second # # usage: ./crop_face_always.py origin_directory dist_directory # import cv2 import math import numpy as np import os import sys import glob import time import shutil def cut_face(origin_path, dist_path) : # åç»åã®å¦ç img_path_list = glob.glob(origin_path + "/*") for img_path in img_path_list: print img_path # ãã¡ã¤ã«å解æ base_name = os.path.basename(img_path) name,ext = os.path.splitext(base_name) if (ext != '.jpg') and (ext != '.jpeg') and (ext != '.png'): print "not a picture" continue img_src = cv2.imread(img_path, 1) # ã°ã¬ã¼ã¹ã±ã¼ã«ã«å¤æ img_gray = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY) #é¡å¤å® faces = cascade.detectMultiScale(img_gray, scaleFactor=1.2, minNeighbors=1, minSize=(10, 10)) # é¡ããã£ãå ´å if len(faces) > 0: i = 0 for (x,y,w,h) in faces: face = img_src[y:y+h, x:x+w] file_name = dist_path + name + "_" + str(i) + ext cv2.imwrite(file_name, face ) i += 1 else: print "not find any faces" shutil.move(img_path, origin_path + "/../finished/") if __name__ == '__main__': # é¡å¤å®ã§ä½¿ãxmlãã¡ã¤ã«ãæå®ããã cascade_path = os.path.dirname(os.path.abspath(__file__)) + "/lbpcascade_animeface.xml" cascade = cv2.CascadeClassifier(cascade_path) # å ¥åã®èªã¿è¾¼ã¿ if len(sys.argv) < 2 : exit() else : origin_path = sys.argv[1] if len(sys.argv) < 3 : dist_path = os.path.dirname(os.path.abspath(__file__)) + "/face/" else : dist_path = sys.argv[2] # æ¯ç§ç»åãå¦ç while(1): cut_face(origin_path, dist_path) time.sleep(1)
ããããªããããã®ãã©ã«ãã«ããæ¾ããã®ç»åãæ¾ãè¾¼ãã§ããé¡ç»åã¯ä¸åã«åºã¦æ¥ã¾ããã 試ãã«ã©ãã©ã¤ãã®ç»åãå ¥ãã¦ã¿ãã¨ãããã«äººæ°ååºã¦ãã¾ãããã©ããããããæ¾ããã®ã¢ãã¡é¢¨ã®é¡ã¯ãã¢ãã¡é¡æ¤åºç¨ã®lbpcascade_animeface.xmlãä½ã£ãæã®ãã¼ã¿ã«å ¥ã£ã¦ããããããæ¾ããã¨ã¯ç¸æ§ãæªãããã§ããèªåã§haarcascadeã®xmlãä½æããã«ã¯ãããã ãã§æ°åæã®ç»åãå¿ è¦ã«ãªãã®ã§ãã¨ã£ã¦ãå³ããã§ãã
é¡ã®åãæã ãdlib使ç¨ç·¨ã
ããã§ãã¡ãã«æ¸ããã¦ããæ¹æ³ã試ãã¾ãã
dlibã«ããHOGç¹å¾´ãç¨ããç©ä½æ¤åºãããã
ãã¡ãã¯dlibã¨ããç»åã©ã¤ãã©ãªã«å®è£ ããã¦ãããHOGç¹å¾´éãSVMã§å¦çãã¦æ¤åºå¨ãä½æããææ³ã§ãããã¡ãã ã¨ç»åã®ææ°ãå°ãªãã¦ãã¿ãã¾ããã¼ã«ãæ¢åã®ãã®ã使ããããããã¡ãã試ãã¾ããã
æµãã¨ãã¦ã¯ã
1, ã¢ãã¡ããã¹ã¯ã·ã§ãããããæ®ã
2, ç»åããé¡ã®ä½ç½®ãæ½åºã座æ¨ã¨ç»åãã¹ã®ãã¼ã¿ãä½æ
3, trainã¨testã«åããxmlå½¢å¼ãã¡ã¤ã«ã«å¤æ
4, SVMã§å¦ç¿ãããæ¤åºå¨ãä½ã
ã¨ãªãã¾ãã
1, ã¢ãã¡ããã¹ã¯ã·ã§ãããããæ®ã
åç»åçããªãããã¹ã¯ãªã¼ã³ã·ã§ãããåãã¾ãã ã¹ã¯ã·ã§ã®åååã³ä¿åå ´æã®å¤æ´ã¯ãã¡ãã«æé ãæ¸ãã¦ããã¾ãã MacbookProã§Cmd+Shift+3ã§ã¹ã¯ã·ã§ãæ®ãã¨ããµã¤ãºã大ããããã®ã§ããã¡ããåèã«1280*800ã«ç¸®å°ãã¾ãã
2, ç»åããé¡ã®ä½ç½®ãæ½åº
ç»åã¨é¡ä½ç½®ã®ãã¼ã¿ãä½æãã¾ãã ä¸è¨ã®é¡åãåãã®pythonã¹ã¯ãªããããä¸é¨ä¿®æ£ãã¦ä½¿ããã¦é ãã¾ããã ã¨ã¦ã便å©ãªä½ãã«ãªã£ã¦ãã¦ãå©ããã¾ããã
ç»åã®ãã©ã«ããæå®ãã¦å®è¡ããã¨ãç»åãç¾ãã¾ãã ãã©ãã°&ããããã§é åãæå®ã§ããã®ã§ããã®ããã«é¡ãå²ãã¾ãã
ããç¨åº¦æ£æ¹å½¢ã«è¿ããªãã¨å¦ç¿ã§ããªãããã§ãæ¯çãæªãã¨ç·ã赤ã«ãªãã確å®ã§ãã¾ããã
ã¡ããã¨ç·ã®ç¶æ ã§ãã©ãã°ã解é¤ããã¨ãç½è²ã§åè§å½¢ãæ®ãã¾ãããã®ããã«å ¨ã¦ã®é¡ãå²ã£ã¦ããã¾ããããééãã¦ãã¾ã£ã¦ãããdããã¼ãæ¼ãã°åãæ¶ãã¾ãã
ãnããã¼ãæ¼ãã¨æ¬¡ã®ç»åã«è¡ããå ¨ã¦ã®ç»åãçµããã¾ã§ç¹°ãè¿ãã¾ãã ä»åã¯150æãç´ï¼æéã»ã©å¦çãã¾ããã
ãã¡ããä¸é¨ä¿®æ£ããã½ã¼ã¹ã§ãã ä¿®æ£ç¹ã¯ããã¡ã¤ã«ãªã¹ãã®å ¥åãæ¨æºå ¥åãããã£ã¬ã¯ããªã®ã¿ãæ¨æºå ¥åã«ããã®ã¨ãå¾è¿°ããå¤æã¹ã¯ãªããã®ããã®ãã°ä¿®æ£ã§ãã
#!/usr/bin/env python #! -*- coding: utf-8 -*- import cv2 import numpy as np import sys import glob drawing = False sx, sy = 0, 0 gx, gy = 0, 0 rectangles = [] ok = False def draw_circle(event,x,y,flags,param): global sx, sy, gx, gy, drawing if event == cv2.EVENT_LBUTTONDOWN: drawing = True sx,sy = x,y elif event == cv2.EVENT_MOUSEMOVE: if x > 0 and x < img.shape[1]: gx = x if y > 0 and y < img.shape[0]: gy = y elif event == cv2.EVENT_LBUTTONUP: drawing = False w = abs(sx-x) h = abs(sy-y) if w < h * 1.1 and h < w * 1.1: rectangles.append([(sx, sy), (x, y)]) img = np.zeros((512, 512, 3), np.uint8) cv2.namedWindow('image') cv2.setMouseCallback('image',draw_circle) i = 0 origin_path = sys.argv[1] img_path_list = glob.glob(origin_path + "*") while i < len(img_path_list): rectangles = [] while True: img = cv2.imread(img_path_list[i]) for r in rectangles: cv2.rectangle(img, r[0], r[1], (255,255,255), 2) if drawing: w = abs(sx-gx) h = abs(sy-gy) if w < h*1.1 and h < w*1.1: color = (0, 255, 0) else: color = (0, 0, 255) cv2.rectangle(img, (sx,sy), (gx,gy), color, 2) cv2.imshow('image', img) k = cv2.waitKey(1) & 0xFF if k == ord('d'): if rectangles: rectangles.pop() elif k == ord('n'): print img_path_list[i], print str(len(rectangles)), for r in rectangles: x = min(r[0][0], r[1][0]) y = min(r[0][1], r[1][1]) w = abs(r[0][0] - r[1][0]) h = abs(r[0][1] - r[1][1]) print x, y, w, h, print break elif k == ord('b'): print 'delete previous line!' if i > 1: i -= 2 break elif k == ord('q'): sys.exit() i += 1
å®è¡ã³ãã³ãã¯ãããªæãã§ãã
$ ./labeling.py ~/Desktop/osomatsu_SS/ > osomatsu.txt
å®è¡ãçµããã¨ããã®ãããªå½¢å¼ã§åãåã£ãé¡ã®åº§æ¨æ å ±ãè¨é²ããã¾ãã
/hoge/Desktop/osomatsu_ss/SS100.png 5 616 131 167 176 401 237 164 156 195 99 136 148 124 283 125 133 729 112 115 122 /hoge/Desktop/osomatsu_ss/SS101.png 1 595 76 461 467 /hoge/Desktop/osomatsu_ss/SS102.png 4 594 43 98 90 71 204 124 122 153 347 114 125 196 25 80 76
ç»åãã¹ é¡åæ° xåº§æ¨ yåº§æ¨ æ¨ªå¹ ç¸¦å¹ ã¨ãã£ãæãã§ãã
3, trainã¨testã«åããxmlå½¢å¼ãã¡ã¤ã«ã«å¤æ
å ã»ã©ä½æãããã¼ã¿ããæ¤åºå¨ä½æå¨ã§ä½¿ããããxmlå½¢å¼ã«å¤æãã¾ãã ãã¡ããä¸è¨ã®å¤æã¹ã¯ãªããããã®ã¾ã¾ä½¿ãã¾ããã
è¨ç·´ç¨ã¨ãã¹ãç¨ã«ï¼ç¨®é¡å¿ è¦ãªã®ã§ãheadã³ãã³ãã§150æåã120:30ã«åãã¦ãxmlãçæãã¾ãã
$ g++ -o gen_xml gen_xml.cpp $ head -120 osomatsu.txt > train.txt $ ./gen_xml > training.xml $ tail -30 osomatsu.txt > train.txt $ ./gen_xml > testing.xml
4, SVMã§å¦ç¿ãããæ¤åºå¨ãä½ã
æå¾ã«æ¤åºå¨ãä½ãã¾ããdlibã®ã¤ã³ã¹ãã¼ã«ã¯ãã¡ãããããåç §ãã¦ãã ããã å ¬å¼ãµã³ãã«ããã¨ã«ãæ¤åºå¨ãä½ã£ãã³ã¼ãã¯ãããªæãã§ãã
#!/usr/bin/python #! -*- coding: utf-8 -*- import os import sys import glob import dlib from skimage import io # å ¥åã«ç»åãã£ã¬ã¯ããªãã¹ãå ¥ããªãã£ãæã®è¦å if len(sys.argv) != 2: print( "Give the path to the examples/faces directory as the argument to this " "program. For example, if you are in the python_examples folder then " "execute this program by running:\n" " ./train_object_detector.py ../examples/faces") exit() faces_folder = sys.argv[1] # å¦ç¿æã®ãã©ã¡ã¼ã¿ options.add_left_right_image_flips = True options.C = 5 options.num_threads = 4 options.be_verbose = True # èªã¿ãããã¡ã¤ã«ãã¹ training_xml_path = os.path.join(faces_folder, "training.xml") testing_xml_path = os.path.join(faces_folder, "testing.xml") # å¦ç¿ dlib.train_simple_object_detector(training_xml_path, "detector.svm", options) # 精度表示 print("") # Print blank line to create gap from previous output print("Training accuracy: {}".format( dlib.test_simple_object_detector(training_xml_path, "detector.svm"))) print("Testing accuracy: {}".format( dlib.test_simple_object_detector(testing_xml_path, "detector.svm")))
ãã¡ããå®è¡ããã³ãã³ãã¯ãã¡ãã§ãã
$ cp training.xml ~/Desktop/osomatsu_SS/ $ cp testing.xml ~/Desktop/osomatsu_SS/ $ ./gen_detector.py ~/Desktop/osomatsu_SS/
ããã§detector.svmã¨ããæ¤åºå¨ãä½æããã¾ãããã¡ãã使ã£ã¦ããæ¾ãããã¡ããã¨æ¤åºãããã試ãã¾ãã
detectorã使ããµã³ãã«ã³ã¼ãã¯ãã¡ãã§ãã
#!/usr/bin/env python #! -*- coding: utf-8 -*- import os import sys import dlib import numpy as np import cv2 # èªã¿ããç»å img = cv2.imread(sys.argv[1],1) out = img.copy() # æ¤åº detector = dlib.simple_object_detector("detector.svm") dets = detector(img) # åè§å½¢æå print str(len(dets)) for d in dets: cv2.rectangle(out, (d.left(), d.top()), (d.right(), d.bottom()), (0, 0, 255), 2) cv2.imshow('image',out) cv2.waitKey(0) cv2.destroyAllWindows()
æ¤åºçµæ
çµæã¯ãã®ããã«ãªã£ã¦ãã¾ãã
OpenCV+AnimeFaceã§ã¯èª°ä¸äººã¨ãã¦æ¤åºãããªãã£ãããæ¾ãããã¡ããã¡ããã¨å ¨å¡æ¤åºããã¦ãã¾ãã
éãªã£ã¦ãã¦ããã¡ããã¨æ¤åºã§ããããã§ãã
ããããã¾ã«æ¤åºãããªãé¡ãããã¾ãã
ã¾ã 精度åä¸ã®ä½å°ã¯ãããããããã使ããæ¤åºå¨ãæ軽ã«ä½ãã¾ããã ãã©ã¡ã¼ã¿ãå¤æ´ãã¦ã¿ãããè¨ç·´ãã¼ã¿ãé¸å¥ãã¦ç²¾åº¦ãåä¸ããããã¨ãèãã¾ããããä»åã¯ã¨ããããããã§é²ãã¾ãã
ç»ååé
å ã»ã©è¿°ã¹ã以ä¸ã®æé ã§ç»åãéãã¾ãã
1, ã¢ãã¡ãæµããªãããå
¨ä½ã®ã¹ã¯ãªã¼ã³ã·ã§ãããæ®ã
2, æå®ãã£ã¬ã¯ããªã«ä¿åãããããã«å
¥ã£ãåçã«å¯¾ãã¦èªåã§é¡ãåãæãã¦ãããããã«ãã
3, åãæãããé¡åçããã¹ã¯ãããã§ãã©ã«ãåããã¦ãã
2ãè¡ã£ã¦ãããã¹ã¯ãªããã¯ä»¥ä¸ã§ãã
#!/usr/bin/env python # -*- coding: UTF-8 -*- # # crop face from all picture in specific directory in every second # # usage: ./crop_face_always.py origin_directory dist_directory # import cv2 import math import numpy as np import os import sys import glob import time import shutil import dlib def cut_face(origin_path, dist_path) : # åç»åã®å¦ç img_path_list = glob.glob(origin_path + "/*") detector = dlib.simple_object_detector("detector.svm") for img_path in img_path_list: print img_path # ãã¡ã¤ã«å解æ base_name = os.path.basename(img_path) name,ext = os.path.splitext(base_name) if (ext != '.jpg') and (ext != '.jpeg') and (ext != '.png'): print "not a picture" continue img_src = cv2.imread(img_path, 1) #é¡å¤å® dets = detector(img_src) # é¡ããã£ãå ´å if len(dets) > 0: i = 0 for d in dets: face = img_src[d.top():d.bottom(), d.left():d.right()] file_name = dist_path + name + "_" + str(i) + ext cv2.imwrite(file_name, face ) i += 1 else: print "not find any faces" shutil.move(img_path, origin_path + "/../finished/") if __name__ == '__main__': # å ¥åã®èªã¿è¾¼ã¿ if len(sys.argv) < 2 : exit() else : origin_path = sys.argv[1] if len(sys.argv) < 3 : dist_path = os.path.dirname(os.path.abspath(__file__)) + "/face/" else : dist_path = sys.argv[2] # æ¯ç§ç»åãå¦ç while(1): cut_face(origin_path, dist_path) time.sleep(1)
ãããªæãã§ã¢ãã¡ãè¦ãªããä½æ¥ãé²ãã¾ãã
ãã¼ã¹ã¯å¤§ä½1æéã§500æç¨åº¦ãã³ãã³ãä½æ¥ãã¦ã2~5話ãã5644æã®ããæ¾ãããã¡ã®ã©ããªã³ã°ãããç»åãéãã¾ããã1話ã¯è²ã ã¨éãã®ã§ããã¾ããã§ããã 以ä¸ã§æºåç·¨ã¯çµããã§ãã次åã¯ãããããéããç»åãç¨ãã¦ãã£ã¼ãã©ã¼ãã³ã°ã§å¦ç¿ããã¾ãã
åè
Deep Learningã§ã©ãã©ã¤ãï¼ãã£ã©ãèå¥ãã