ðViola-Jonesç©äœæ€åºãã¬ãŒã ã¯ãŒã¯
Viola-Jonesç©äœæ€åºãã¬ãŒã ã¯ãŒã¯ã¯ãäž»ã«é¡æ€åºã«äœ¿çšãããé«éãªãªããžã§ã¯ãæ€åºã¢ã«ãŽãªãºã ã§ãããã®ãã¬ãŒã ã¯ãŒã¯ã¯ãç©åç»åãHaar-likeç¹åŸŽãAdaBoostãã«ã¹ã±ãŒãåé¡åšã®4ã€ã®äž»èŠãªã³ã³ããŒãã³ãã䜿çšããŸãã以äžã¯ããã®ããã»ã¹ãç䌌ã³ãŒããšããŠè¡šãããã®ã§ãã
def viola_jones_detection(image):
# ã¹ããã 1: ç©åç»åãèšç®
integral_image = compute_integral_image(image)
# ã¹ããã 2: 䜿çšããHaar-likeç¹åŸŽã®ã»ãããéžæ
features = select_haar_features()
# ã¹ããã 3: AdaBoostã䜿çšããŠç¹åŸŽã匷å
classifiers = train_adaboost(features, training_data)
# ã¹ããã 4: åé¡åšã®ã«ã¹ã±ãŒããæ§ç¯
cascade = build_classifier_cascade(classifiers)
# æ€åºããã»ã¹
detected_objects = []
for (x, y, window_size) in sliding_window(image):
window_integral = compute_window_integral(integral_image, x, y, window_size)
if cascade_classify(cascade, window_integral):
detected_objects.append((x, y, window_size))
return detected_objects
def compute_integral_image(image):
# ç©åç»åãèšç®ããé¢æ° (åã®èª¬æãåç
§)
pass
def select_haar_features():
# Haar-likeç¹åŸŽã®ã»ãããéžæãã
# ãã®ã¹ãããã§ã¯ãé¡æ€åºã«æçšãªç¹åŸŽã®ã¿ã€ãããµã€ãºãå®çŸ©ããŸãã
pass
def train_adaboost(features, training_data):
# AdaBoostã¢ã«ãŽãªãºã ã䜿çšããŠåŒ±åé¡åšãèšç·Žããããããçµã¿åãããŠåŒ·åé¡åšãäœæ
pass
def build_classifier_cascade(classifiers):
# åé¡åšã®ã«ã¹ã±ãŒããæ§ç¯ãå段éã§ã¯ãåã®æ®µéãééãããŠã£ã³ããŠã®ã¿ã次ã®æ®µéã«é²ã
pass
def sliding_window(image):
# ç»åäžã移åããã¹ã©ã€ãã£ã³ã°ãŠã£ã³ããŠãçæããã€ãã¬ãŒã¿
# ãã®é¢æ°ã¯ãæ€æ»ãããŠã£ã³ããŠã®äœçœ®ãšãµã€ãºãè¿ã
pass
def compute_window_integral(integral_image, x, y, window_size):
# æå®ããããŠã£ã³ããŠã®ç©åç»åãèšç®
pass
def cascade_classify(cascade, window_integral):
# äžãããããŠã£ã³ããŠã«å¯ŸããŠã«ã¹ã±ãŒãåé¡åšãé©çšããç©äœãååšãããã©ãããå€æ
pass
Viola-Jonesç©äœæ€åºãã¬ãŒã ã¯ãŒã¯ã¯ãPaul ViolaãšMichael Jonesã«ãã£ãŠ2001幎ã«æå±ãããæ©æ¢°åŠç¿ã«ããç©äœæ€åºãã¬ãŒã ã¯ãŒã¯ã§ãããäž»ã«é¡æ€åºã®åé¡ã«åæ©ã¥ããããŠããã
ãã®ã¢ã«ãŽãªãºã ã¯ãåŸæ¥ã®700MHz Intel Pentium IIIã§ã384Ã288ãã¯ã»ã«ã®ç»åãã15ãã¬ãŒã /ç§ã§é¡ãæ€åºããããšãã§ããæéã«å¯ŸããŠå¹ççã§ããããŸãããã¹ãã§ãããé«ã粟床ãšåçŸçãéæããŠããã
ç³ã¿èŸŒã¿ãã¥ãŒã©ã«ãããã¯ãŒã¯ã®ãããªææ°ã®ææ³ã«æ¯ã¹ããšç²ŸåºŠã¯å£ããããã®å¹çæ§ãšã³ã³ãã¯ããªãµã€ãºïŒDeepFaceã®ãããªå žåçãªCNNã®æ°çŸäžã®ãã©ã¡ãŒã¿ã«æ¯ã¹ãããã50kçšåºŠã®ãã©ã¡ãŒã¿ïŒã«ãããèšç®èœåãéãããŠããå Žåã§ã䜿çšããããäŸãã°ããªãªãžãã«ã®è«æã§ã¯ããã®é¡æ€åºåšã¯Compaq iPAQäžã§2fpsã§å®è¡ã§ãããšå ±åãããŠããïŒãã®ããã€ã¹ã«ã¯ãæµ®åå°æ°ç¹ããŒããŠã§ã¢ãæããªãäœæ¶è²»é»åã®StrongARMãæèŒãããŠããïŒã
Wikipediaã§ã®è§£èª¬
ViolaâJonesãã¬ãŒã ã¯ãŒã¯ã®äž»ãªç¹åŸŽãšããŠã以äžã®4ã€ã®ããŒæè¡ãæããããŸãã
ç©åç»å (Integral Image): ç»åå ã®ä»»æã®ç©åœ¢é åã®ãã¯ã»ã«å€ã®åèšãé«éã«èšç®ã§ããããŒã¿æ§é ãããã«ãããç¹åŸŽã®ã¹ã±ãŒãªã³ã°ãšäœçœ®ã®å€æŽã容æã«ãªããèšç®é床ãå€§å¹ ã«åäžããŸãã
ã¢ãããŒã¹ã (AdaBoost) åŠç¿ã¢ã«ãŽãªãºã : 匱ãåé¡åšïŒåçŽãªç¹åŸŽã«åºã¥ãå€æãè¡ãåé¡åšïŒãçµã¿åãããŠãããæ£ç¢ºãªåŒ·ãåé¡åšãäœæããåŠç¿ã¢ã«ãŽãªãºã ãViolaâJonesãã¬ãŒã ã¯ãŒã¯ã§ã¯ãé¡æ€åºã«é¢é£ããç¹åŸŽãéžæããéé¡ãšåºå¥ããããã«äœ¿çšãããŸãã
ã«ã¹ã±ãŒãåé¡åš: æ€åºããã»ã¹ãè€æ°ã®æ®µéã«åããå段éã§ãªããžã§ã¯ãïŒäŸãã°ãé¡ïŒã§ãªããšå€æãããé åãæé€ããããšã«ãããèšç®éãåæžããŸããæãç°¡åãªç¹åŸŽããå§ãŸããåŸã ã«ããè€éãªç¹åŸŽãçšããŠåæãè¡ãããŸããããã«ãããéé¡é åãè¿ éã«æé€ããæ€åºããã»ã¹ã®å¹çãé«ããããšãã§ããŸãã
ããŒã«æ§ç¹åŸŽ (Haar-like Features): ç»åå ã®ç¹å®ã®åœ¢ç¶ãèå¥ããããã«äœ¿çšããããã·ã³ãã«ã§å¹æçãªç¹åŸŽããããã¯ãé¡ã®ãããªãªããžã§ã¯ãã«ç¹æã®ææã®ãã¿ãŒã³ïŒäŸãã°ãç®ã®åšãã®æãé åãšéŒ»ã®æ©ã®æããé åïŒãæ€åºããã®ã«é©ããŠããŸãã
ViolaâJonesãã¬ãŒã ã¯ãŒã¯ã¯ããã®é«éæ§ãšå¹çæ§ã®ããã«ãç£èŠã«ã¡ã©ãç»åç·šéãœãããŠã§ã¢ãããã³ãã®ä»ã®å€ãã®ã¢ããªã±ãŒã·ã§ã³ã§åºãå©çšãããŠããŸãããŸãããã®ãã¬ãŒã ã¯ãŒã¯ã¯é¡æ€åºæè¡ã®ç 究ã«ãããåºç€ãšããŠãæ©èœããåŸç¶ã®ç 究ã«å€§ããªåœ±é¿ãäžããŸããã
Viola-Jonesãªããžã§ã¯ãæ€åºãã¬ãŒã ã¯ãŒã¯ã§ã¯Haarç¹åŸŽéãå©çšãããŠããŸãã
Haarç¹åŸŽéã¯ãç»åå ã®ç¹å®ã®åœ¢ç¶ããã¿ãŒã³ãèå¥ããããã«èšèšããããã·ã³ãã«ãªããã匷åãªç¹åŸŽéã§ãããããã®ç¹åŸŽéã¯ãç»åã®æããã®å€åãå©çšããŠãäŸãã°é¡ã®æ§é ã®ãããªãªããžã§ã¯ãã®ç¹æ§ãæããŸãã
Haarç¹åŸŽéã¯ãç©åœ¢é åå ã®ãã¯ã»ã«å€ã®å·®ãèšç®ããããšã«åºã¥ããŠããŸãããããã®ç©åœ¢ã¯ç»åäžã§æ§ã ãªäœçœ®ããµã€ãºã圢ç¶ã«èª¿æŽãããé¡ã®ãããªãªããžã§ã¯ããæã€å žåçãªç¹åŸŽïŒäŸïŒç®ãšé ¬ã®éã®ã³ã³ãã©ã¹ãïŒãæ€åºããã®ã«äœ¿çšãããŸããHaarç¹åŸŽéã¯ãç©åç»åã®æŠå¿µãå©çšããŠé«éã«èšç®ããããšãã§ãããã®é«éèšç®ããªã¢ã«ã¿ã€ã ã®ãªããžã§ã¯ãæ€åºãå¯èœã«ããŠããŸãã
Haarç¹åŸŽéã«ã¯äž»ã«3çš®é¡ããããŸãïŒ
ãšããžç¹åŸŽé: ç»åã®ç¹å®ã®é åå ã§æãããæ¥æ¿ã«å€åããå Žæãæ€åºããŸããããã¯äŸãã°ãé¡ã®å¢çã錻ã®æ©ãªã©ããšããžã茪éãæçãªé åãèå¥ããã®ã«æå¹ã§ãã
ã©ã€ã³ç¹åŸŽé: æããé åãšæãé åã亀äºã«çŸãããã¿ãŒã³ãæ€åºããŸããããã¯ãé¡ã®ç¹å®ã®éšåãäŸãã°ç®ã®äžã®åœ±ãªã©ã现ããç·ç¶ã®ãã¿ãŒã³ãèå¥ããã®ã«é©ããŠããŸãã
åè§ç¹åŸŽé: 4ã€ã®é£æ¥ããç©åœ¢é åã®ãã¡ã察è§ç·äžã«äœçœ®ãã2ã€ã®é åãæãããæ®ãã®2ã€ãæããšãããã¿ãŒã³ãæ€åºããŸããããã¯ãããè€éãªåœ¢ç¶ããã¯ã¹ãã£ã®èå¥ã«åœ¹ç«ã¡ãŸãã
ãããã®ç¹åŸŽéã¯ãã¢ãããŒã¹ãåŠç¿ã¢ã«ãŽãªãºã ã«ãã£ãŠéžæãããæãèå¥åã®ããç¹åŸŽã®ã¿ããªããžã§ã¯ãïŒé¡ïŒæ€åºã®æçµã¢ãã«ã«çµã¿èŸŒãŸããŸããHaarç¹åŸŽéã®äœ¿çšã¯ãViola-Jonesãã¬ãŒã ã¯ãŒã¯ã®å¹çæ§ãšç²ŸåºŠã®äž¡æ¹ãå€§å¹ ã«åäžãããŠããŸãã
Viola-Jonesã¯åºæ¬çã«ããŒã¹ãç¹åŸŽåŠç¿ã¢ã«ãŽãªãºã
OpenCV
åé¡åšã®ã«ã¹ã±ãŒã
ç©åç»å(Integral Image)ãŸãã¯é¢ç©åè¡š
def compute_integral_image(image):
import numpy as np
integral_image = np.zeros_like(image, dtype=np.int32)
integral_image[0, 0] = image[0, 0]
for x in range(1, image.shape[1]):
integral_image[0, x] = integral_image[0, x-1] + image[0, x]
for y in range(1, image.shape[0]):
integral_image[y, 0] = integral_image[y-1, 0] + image[y, 0]
for y in range(1, image.shape[0]):
for x in range(1, image.shape[1]):
integral_image[y, x] = (image[y, x] +
integral_image[y-1, x] +
integral_image[y, x-1] -
integral_image[y-1, x-1])
return integral_image
# å
¥åç»å
image = np.array([[10, 20, 30],
[40, 50, 60],
[70, 80, 90]])
# ç©åç»åã®èšç®
integral_image = compute_integral_image(image)
ãé¡ãèŽããŸã