<s> import sys <EOL> import os <EOL> import cv2 <EOL> import numpy as np <EOL> class Detector : <EOL> def detect ( self , src ) : <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> class SkinDetector ( Detector ) : <EOL> """<STR_LIT>""" <EOL> def _R1 ( self , BGR ) : <EOL> B = BGR [ : , : , <NUM_LIT:0> ] <EOL> G = BGR [ : , : , <NUM_LIT:1> ] <EOL> R = BGR [ : , : , <NUM_LIT:2> ] <EOL> e1 = ( R > <NUM_LIT> ) & ( G > <NUM_LIT> ) & ( B > <NUM_LIT:20> ) & ( ( np . maximum ( R , np . maximum ( G , B ) ) - np . minimum ( R , np . minimum ( G , B ) ) ) > <NUM_LIT:15> ) & ( np . abs ( R - G ) > <NUM_LIT:15> ) & ( R > G ) & ( R > B ) <EOL> e2 = ( R > <NUM_LIT> ) & ( G > <NUM_LIT> ) & ( B > <NUM_LIT> ) & ( abs ( R - G ) <= <NUM_LIT:15> ) & ( R > B ) & ( G > B ) <EOL> return ( e1 | e2 ) <EOL> def _R2 ( self , YCrCb ) : <EOL> Y = YCrCb [ : , : , <NUM_LIT:0> ] <EOL> Cr = YCrCb [ : , : , <NUM_LIT:1> ] <EOL> Cb = YCrCb [ : , : , <NUM_LIT:2> ] <EOL> e1 = Cr <= ( <NUM_LIT> * Cb + <NUM_LIT:20> ) <EOL> e2 = Cr >= ( <NUM_LIT> * Cb + <NUM_LIT> ) <EOL> e3 = Cr >= ( - <NUM_LIT> * Cb + <NUM_LIT> ) <EOL> e4 = Cr <= ( - <NUM_LIT> * Cb + <NUM_LIT> ) <EOL> e5 = Cr <= ( - <NUM_LIT> * Cb + <NUM_LIT> ) <EOL> return e1 & e2 & e3 & e4 & e5 <EOL> def _R3 ( self , HSV ) : <EOL> H = HSV [ : , : , <NUM_LIT:0> ] <EOL> S = HSV [ : , : , <NUM_LIT:1> ] <EOL> V = HSV [ : , : , <NUM_LIT:2> ] <EOL> return ( ( H < <NUM_LIT> ) | ( H > <NUM_LIT> ) ) <EOL> def detect ( self , src ) : <EOL> if np . ndim ( src ) < <NUM_LIT:3> : <EOL> return np . ones ( src . shape , dtype = np . uint8 ) <EOL> if src . dtype != np . uint8 : <EOL> return np . ones ( src . shape , dtype = np . uint8 ) <EOL> srcYCrCb = cv2 . cvtColor ( src , cv2 . COLOR_BGR2YCR_CB ) <EOL> srcHSV = cv2 . cvtColor ( src , cv2 . COLOR_BGR2HSV ) <EOL> skinPixels = self . _R1 ( src ) & self . _R2 ( srcYCrCb ) & self . _R3 ( srcHSV ) <EOL> return np . asarray ( skinPixels , dtype = np . uint8 ) <EOL> class CascadedDetector ( Detector ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cascade_fn = "<STR_LIT>" , scaleFactor = <NUM_LIT> , minNeighbors = <NUM_LIT:5> , minSize = ( <NUM_LIT:30> , <NUM_LIT:30> ) ) : <EOL> if not os . path . exists ( cascade_fn ) : <EOL> raise IOError ( "<STR_LIT>" % cascade_fn ) <EOL> self . cascade = cv2 . CascadeClassifier ( cascade_fn ) <EOL> self . scaleFactor = scaleFactor <EOL> self . minNeighbors = minNeighbors <EOL> self . minSize = minSize <EOL> def detect ( self , src ) : <EOL> if np . ndim ( src ) == <NUM_LIT:3> : <EOL> src = cv2 . cvtColor ( src , cv2 . COLOR_BGR2GRAY ) <EOL> src = cv2 . equalizeHist ( src ) <EOL> rects = self . cascade . detectMultiScale ( src , scaleFactor = self . scaleFactor , minNeighbors = self . minNeighbors , minSize = self . minSize ) <EOL> if len ( rects ) == <NUM_LIT:0> : <EOL> return np . ndarray ( ( <NUM_LIT:0> , ) ) <EOL> rects [ : , <NUM_LIT:2> : ] += rects [ : , : <NUM_LIT:2> ] <EOL> return rects <EOL> class SkinFaceDetector ( Detector ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , threshold = <NUM_LIT> , cascade_fn = "<STR_LIT>" , scaleFactor = <NUM_LIT> , minNeighbors = <NUM_LIT:5> , minSize = ( <NUM_LIT:30> , <NUM_LIT:30> ) ) : <EOL> self . faceDetector = CascadedDetector ( cascade_fn = cascade_fn , scaleFactor = scaleFactor , minNeighbors = minNeighbors , minSize = minSize ) <EOL> self . skinDetector = SkinDetector ( ) <EOL> self . threshold = threshold <EOL> def detect ( self , src ) : <EOL> rects = [ ] <EOL> for i , r in enumerate ( self . faceDetector . detect ( src ) ) : <EOL> x0 , y0 , x1 , y1 = r <EOL> face = src [ y0 : y1 , x0 : x1 ] <EOL> skinPixels = self . skinDetector . detect ( face ) <EOL> skinPercentage = float ( np . sum ( skinPixels ) ) / skinPixels . size <EOL> print skinPercentage <EOL> if skinPercentage > self . threshold : <EOL> rects . append ( r ) <EOL> return rects <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> if len ( sys . argv ) < <NUM_LIT:2> : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> inFileName = sys . argv [ <NUM_LIT:1> ] <EOL> outFileName = None <EOL> if len ( sys . argv ) > <NUM_LIT:2> : <EOL> outFileName = sys . argv [ <NUM_LIT:2> ] <EOL> if outFileName == inFileName : <EOL> outFileName = None <EOL> img = np . array ( cv2 . imread ( inFileName ) , dtype = np . uint8 ) <EOL> imgOut = img . copy ( ) <EOL> detector = CascadedDetector ( cascade_fn = "<STR_LIT>" ) <EOL> eyesDetector = CascadedDetector ( scaleFactor = <NUM_LIT> , minNeighbors = <NUM_LIT:5> , minSize = ( <NUM_LIT:20> , <NUM_LIT:20> ) , cascade_fn = "<STR_LIT>" ) <EOL> for i , r in enumerate ( detector . detect ( img ) ) : <EOL> x0 , y0 , x1 , y1 = r <EOL> cv2 . rectangle ( imgOut , ( x0 , y0 ) , ( x1 , y1 ) , ( <NUM_LIT:0> , <NUM_LIT:255> , <NUM_LIT:0> ) , <NUM_LIT:1> ) <EOL> face = img [ y0 : y1 , x0 : x1 ] <EOL> for j , r2 in enumerate ( eyesDetector . detect ( face ) ) : <EOL> ex0 , ey0 , ex1 , ey1 = r2 <EOL> cv2 . rectangle ( imgOut , ( x0 + ex0 , y0 + ey0 ) , ( x0 + ex1 , y0 + ey1 ) , ( <NUM_LIT:0> , <NUM_LIT:255> , <NUM_LIT:0> ) , <NUM_LIT:1> ) <EOL> if outFileName is None : <EOL> cv2 . imshow ( '<STR_LIT>' , imgOut ) <EOL> cv2 . waitKey ( <NUM_LIT:0> ) <EOL> cv2 . imwrite ( outFileName , imgOut ) </s>
