def __find_eyes(img): coords = [] face_cascade = CascadeClassifier( bin_path + '/Resources/Classifiers/haarcascade_frontalface.xml') eye_cascade = CascadeClassifier( bin_path + '/Resources/Classifiers/haarcascade_eye.xml') gray = array(img.convert("L")) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: roi_gray = gray[y:y + h, x:x + w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex, ey, ew, eh) in eyes: coords.append((x + ex + ew / 2, y + ey + eh / 2)) return coords
def main(): image_list = [ file for file in os.listdir('Dataset') if file.endswith('.jpg') ] image_list.sort() # load the pre-trained model classifier = CascadeClassifier('lbpcascade_frontalface.xml') j = 0 for i in image_list[:10]: j = j + 1 # load the photograph pixels = imread('Dataset/' + i) # perform face detection bboxes = classifier.detectMultiScale(pixels) # print bounding box for each detected face #print('Number of faces detected in '+i+' : '+str(len(bboxes))) for box in bboxes: # extract x, y, width, height = box x2, y2 = x + width, y + height # draw a rectangle over the pixels rectangle(pixels, (x, y), (x2, y2), (0, 0, 255), 2) imwrite('Output/Face_Detection_LBP' + str(i), pixels)
def detect_face_cv2_webcam(): cap = VideoCapture(0) classifier = CascadeClassifier('haarcascade_frontalface_default.xml') # Check if the webcam is opened correctly if not cap.isOpened(): raise IOError("Cannot open webcam") while True: ret, frame = cap.read() frame = flip(frame, 1) gray = cvtColor(frame, COLOR_BGR2GRAY) faces = classifier.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), # flags=cv2.cv.CV_HAAR_SCALE_IMAGE ) for (x, y, w, h) in faces: rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2) imshow("Video", frame) if waitKey(1) == ord('q'): break cap.release() destroyAllWindows()
class FaceExtractorCascadePipe(FaceExtractorPipe): def __init__( self, cascadeXMLFilePath: str = './resources/face_detectors/facedetect_haarcascade_frontalface_default.xml', postProcessCallback=None): super().__init__(postProcessCallback=postProcessCallback) # check if file exists open(cascadeXMLFilePath, 'r').close() self.face_cascade = CascadeClassifier(cascadeXMLFilePath) def getFaceBB(self, image: Image_Type, passThrough: PushPipe.PassThrough) -> Image_Type: gray = cvtColor(image, COLOR_RGB2GRAY) faces = self.face_cascade.detectMultiScale(gray, 1.3, 5) if (len(faces) > 0): # get largest face largest = (0, 0, 0, 0) for (x, y, w, h) in faces: if (largest[-1] * largest[-2] < w * h): largest = (x, y, w, h) (x, y, w, h) = largest rect = BoundingBox_twopoint(x, y, x + w, y + h) return rect else: # no faces found, won't push forward self.setErrored("No face found.") return image
def cropFace(img): # load the photograph # pixels = img pixels = img # load the pre-trained model classifier = CascadeClassifier( 'face_detect/haarcascade_frontalface_default.xml') # perform face detection bboxes = classifier.detectMultiScale(pixels) if len(bboxes) == 0: print("ERROR: No faces found.") # extract x, y, width, height = bboxes[0] x2, y2 = x + width, y + height BUFFER = int(width * 0.25) # show the image image = pixels[max(y - BUFFER, 0):min(y2 + BUFFER, pixels.shape[0]), max(x - BUFFER, 0):min(x2 + BUFFER, pixels.shape[1])] # imshow('hehe', image) # waitKey(0) return image
def crop(self, input_image, output_filename=None, to_gray=False): image = asarray(input_image) img_height, img_width = image.shape[:2] minface = int(sqrt(img_height ** 2 + img_width ** 2) / self.minface) # create the haar cascade face_cascade = CascadeClassifier(self.casc_path) # detect faces in the image faces = face_cascade.detectMultiScale( cvtColor(image, COLOR_BGR2GRAY), scaleFactor=1.1, minNeighbors=5, minSize=(minface, minface), flags=CASCADE_FIND_BIGGEST_OBJECT | CASCADE_DO_ROUGH_SEARCH, ) # handle no faces if len(faces) == 0: return None # make padding from biggest face found x, y, w, h = faces[-1] pos = self._crop_positions(img_height, img_width, x, y, w, h,) # actual cropping image = image[pos[0]: pos[1], pos[2]: pos[3]] # resize image = resize(image, (self.width, self.height), interpolation=INTER_AREA) if output_filename: if to_gray: Image.fromarray(image).convert("L").save(output_filename) else: cv2.imwrite(output_filename, image) return image
def face_detection(self) -> bool: """Detects faces by converting it to grayscale and neighbor match method. Returns: bool: A boolean value if not a face was detected. """ cascade = CascadeClassifier(data.haarcascades + "haarcascade_frontalface_default.xml") for _ in range(20): ignore, image = self.validation_video.read( ) # reads video from web cam scale = cvtColor( image, COLOR_BGR2GRAY) # convert the captured image to grayscale scale_factor = 1.1 # specify how much the image size is reduced at each image scale min_neighbors = 5 # specify how many neighbors each candidate rectangle should have to retain it faces = cascade.detectMultiScale( scale, scale_factor, min_neighbors) # faces are listed as tuple here # This is a hacky way to solve the problem. The problem when using "if faces:": # ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() # When used either of the suggestion: # AttributeError: 'tuple' object has no attribute 'any' / 'all' # But happens only when the value is true so ¯\_(ツ)_/¯ try: if faces: pass except ValueError: imwrite('cv2_open.jpg', image) self.validation_video.release() return True
def extract_face_opencv(f_cascade: cv2.CascadeClassifier, image: np.ndarray, scale_factor=1.1, size=-1, padding_ratio=0.5) \ -> List[np.ndarray]: gray = cv2.cvtColor(image.copy(), cv2.COLOR_RGB2GRAY) # let's detect multiscale (some images may be closer to camera than others) images bboxes = f_cascade.detectMultiScale(gray, scaleFactor=scale_factor, minNeighbors=5) res = [] for (x, y, w, h) in bboxes: bbox = [x, y, x + w, y + h] width = bbox[2] - bbox[0] height = bbox[3] - bbox[1] bbox = [ int(bbox[0] - width * padding_ratio // 2), int(bbox[1] - height * padding_ratio // 2), int(bbox[2] + width * padding_ratio // 2), int(bbox[3] + height * padding_ratio // 2) ] width = bbox[2] - bbox[0] height = bbox[3] - bbox[1] padding_width_face = (height - width if height > width else 0) // 2 padding_height_face = (width - height if width > height else 0) // 2 bbox = [ bbox[0] - padding_width_face, bbox[1] - padding_height_face, bbox[2] + padding_width_face, bbox[3] + padding_height_face ] left_shift = abs(bbox[0]) if bbox[0] < 0 else 0 right_shift = bbox[2] - image.shape[1] if bbox[2] > image.shape[ 1] else 0 top_shift = abs(bbox[1]) if bbox[1] < 0 else 0 bottom_shift = bbox[3] - image.shape[0] if bbox[3] > image.shape[ 0] else 0 bbox[0] += left_shift bbox[0] -= right_shift bbox[1] += top_shift bbox[1] -= bottom_shift bbox[2] += left_shift bbox[2] -= right_shift bbox[3] += top_shift bbox[3] -= bottom_shift face = image[bbox[1]:bbox[3], bbox[0]:bbox[2], :] if size == -1 else \ cv2.resize(image[bbox[1]:bbox[3], bbox[0]:bbox[2], :], (size, size)) res.append(face) return res
class GenericFaceDetection(object): def __init__(self, fl, lock, fps=None): # Reference to lock > I'm not sure if I am doing this correctly self.lock = lock # Reference to the FrameLoop object (instance) self.fl_ref = fl # The target fps self.target_fps = fps if fps else fl.fps # The current frame of the FrameLoop self.frame = None # The current frame of the FrameLoop (.jpg encoded) self.encodedFrame = None # Classifier reference self.face_cascade = CascadeClassifier(data.haarcascades + 'haarcascade_frontalface_default.xml') def detect_generic_face(self): while True: # Grab the lock with self.lock: # Make a copy of the frame loop's current frame self.frame = self.fl_ref.frame.copy() # Try to detect faces in the current faces = self.face_cascade.detectMultiScale(self.frame, 1.35, 5) # Draw the rectangle around each face for (x, y, w, h) in faces: rectangle(self.frame, (x, y), (x+w, y+h), (255, 0, 0), 2) # Sleep until the time for the next frame sleep(1/self.target_fps) def encoding_generator(self): while True: # Grab the lock with self.lock: # Encode the frame into the `encodedImage` variable (flag, self.encodedImage) = imencode(".jpg", self.frame) # Check if encoding was successful if flag: yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + bytearray(self.encodedImage) + b'\r\n') # Else just skip else: print("Error encoding to .jpg ~(detect_generic_face)") continue def start(self): # Run the generic face detection in another thread self.t = Thread(target=self.detect_generic_face) self.t.daemon = True self.t.start()
def extract_faces(classifier: cv2.CascadeClassifier, image: array) -> Iterator[array]: """ 画像から顔を検出して、顔の部分を切り取った画像をyieldする。 """ # 顔検出を高速化するため、画像をグレースケールに変換する。 gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 顔を検出する。 faces = classifier.detectMultiScale(gray_image) # 検出した顔のリストについて反復処理する。 for x, y, w, h in faces: yield image[y:y + h, x:x + w] # 顔の部分だけを切り取った画像をyieldする。
def start(q, postURLe): global embeddedDB global postURL postURL = postURLe embedUpdateTimeout = 0 fetchEmbedded() detector = CascadeClassifier("haarcascade_frontalface_default.xml") prevName = None while True: time.sleep(0.1) if (not (q.empty())): if (embedUpdateTimeout == 6): #fetchEmbedded() embedUpdateTimeout = 0 frame = imutils.resize(q.get(), width=500) frame = cvtColor(frame, COLOR_BGR2RGB) frameGray = cvtColor(frame, COLOR_BGR2GRAY) rects = detector.detectMultiScale(frame, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=CASCADE_SCALE_IMAGE) boxes = [(y, x + w, y + h, x) for (x, y, w, h) in rects] sendBoxes = [(x, y, x + w, y + h) for (x, y, w, h) in rects] encodings = face_recognition.face_encodings(frame, boxes) names = [] for encoding in encodings: matches = face_recognition.compare_faces( embeddedDB["encodings"], encoding, tolerance=0.48) name = "Unknown" if True in matches: matchedIdxs = [i for (i, b) in enumerate(matches) if b] counts = {} for i in matchedIdxs: name = embeddedDB["names"][i] counts[name] = counts.get(name, 0) + 1 name = max(counts, key=counts.get) names.append(name) if (len(names) > 0): if (prevName == names[0]): eventLogger.eventLogger(frame, sendBoxes[0], names[0], postURL) if (names[0] != "Unknown"): print("Recognized: " + names[0]) lockCtrl.unlock() else: print("Unrecognized stranger!") prevName = names[0] else: eventLogger.eventLogger(frame, None, None, postURL) embedUpdateTimeout += 1
def detect_face_opencv_haar(face_cascade: cv2.CascadeClassifier, frame: numpy.ndarray, i_w: int, in_height=300): """ Take haar_cascade and frame (img), search faces in the frame, select face with size 'iw' :param face_cascade: haarCascade obj :param frame: image for face detecting :param i_w: out img size :param in_height: default height for template img for haarDetector algorithm :return: out img (cut to iw) """ iw_h = i_w >> 1 # half of img width frame_open_cv_haar = frame.copy() frame_height = frame_open_cv_haar.shape[0] frame_width = frame_open_cv_haar.shape[1] in_width = int((frame_width / frame_height) * in_height) frame_open_cv_haar_small = cv2.resize(frame_open_cv_haar, (in_width, in_height)) faces = face_cascade.detectMultiScale( cv2.cvtColor(frame_open_cv_haar_small, cv2.COLOR_BGR2GRAY)) # choose the first face, find center of rect if not list(faces): # if no face detected select the middle of the picture roi = get_roi(int(frame_width / 2), int(frame_height / 2), frame_width, frame_height, iw_h) out_small_image = frame_open_cv_haar[roi[1] - iw_h:roi[1] + iw_h - 1, roi[0] - iw_h:roi[0] + iw_h - 1].copy() else: # faces are detected, select one of them x_center = int( (faces[0][0] + faces[0][2] / 2) * (frame_width / in_width)) y_center = int( (faces[0][1] + faces[0][3] / 2) * (frame_height / in_height)) roi = get_roi(x_center, y_center, frame_width, frame_height, iw_h) out_small_image = frame_open_cv_haar[roi[1] - iw_h:roi[1] + iw_h - 1, roi[0] - iw_h:roi[0] + iw_h - 1].copy() # logger.debug(VisualRecord("Haar face detector " + str(datetime.datetime.utcnow()), # [frame_open_cv_haar, out_small_image], "bla bla", fmt="png")) return out_small_image
class FaceDetector: def __init__(self, faceCascadePath): self.faceCascade = CascadeClassifier(faceCascadePath) def track_faces(self, image): rects = [] face_rects = self.faceCascade.detectMultiScale( image, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) for (fX, fY, fH, fW) in face_rects: rects.append((fX, fY, fX + fW, fY + fH)) return (face_rects, rects)
def crop_face(img): """ Given an image with a single face, crop the face out and return it. :param img: :return: """ # get face classifier face_cascade = CascadeClassifier( "../data/haarcascades/haarcascade_frontalface_default.xml") # detect all faces detected = face_cascade.detectMultiScale(img, 1.2, 5) # get first face detected (probably the largest one) (x, y, w, h) = detected[0] # return cropped image return img[y:y + w, x:x + h]
def main(): if(len(sys.argv)!=4): print("Wrong number of arguments.") print(" Usage: ./bin/pre_annotate.py <file.txt> <image_dir> <output_dir>") sys.exit(0) localizer = bob.ip.flandmark.Flandmark() files = open(sys.argv[1]).readlines() if os.environ.has_key('SGE_TASK_ID'): pos = int(os.environ['SGE_TASK_ID']) - 1 if pos >= len(files): raise RuntimeError, "Grid request for job %d on a setup with %d jobs" % \ (pos, len(files)) files = [files[pos]] for o in files: filename = os.path.join(sys.argv[2], o.rstrip("\n")) output_filename = os.path.join(sys.argv[3], o.rstrip("\n")+".pos") img = bob.io.base.load(filename) if(len(img.shape)==3): img = bob.ip.color.rgb_to_gray(img) cc = CascadeClassifier('./pre_annotation/data/haarcascade_frontalface_alt2.xml') face_bbxs = cc.detectMultiScale(img, 1.3, 4, 0, (20, 20)) if(len(face_bbxs)>0): key_temp = localizer.locate(img, face_bbxs[0][1], face_bbxs[0][0], face_bbxs[0][2], face_bbxs[0][3]) if(key_temp is not None): R_eye = [ (key_temp[1,0] + key_temp[5,0])/2, (key_temp[1,1] + key_temp[5,1])/2 ] L_eye = [ (key_temp[2,0] + key_temp[6,0])/2, (key_temp[2,1] + key_temp[6,1])/2 ] keypoints = [int(L_eye[1]), int(L_eye[0]), int(R_eye[1]), int(R_eye[0])] else: keypoints = [100,100,100,200] else: keypoints = [100,100,100,200] print("{0}: {1}".format(filename,str(keypoints))) bob.io.base.create_directories_safe(os.path.dirname(output_filename)) annotations = "L R\n0 {0} {1} {2} {3}".format(str(keypoints[0]), str(keypoints[1]), str(keypoints[2]), str(keypoints[3])) open(output_filename,'w').write(annotations)
def opencv_detect(image): """Detects a face using OpenCV's cascade detector Returns a list of arrays containing (x, y, width, height) for each detected face. """ from cv2 import CascadeClassifier cc = CascadeClassifier(F('haarcascade_frontalface_alt.xml')) return cc.detectMultiScale( image, 1.3, #scaleFactor (at each time the image is re-scaled) 4, #minNeighbors (around candidate to be retained) 0, #flags (normally, should be set to zero) (20,20), #(minSize, maxSize) (of detected objects on that scale) )
def detect_face_in_image( cv_gray: np.ndarray, face_cascade: cv2.CascadeClassifier, ) -> Tuple[Tuple[int], int]: """Run the face detector, and return the coordinates (x,y,w,h) for the the FIRST rectangle containing a detected face in the list. (Note: There should never be more than one person on a picture, if more faces are detected we will simply use the first in the list.) If no face is detected, the tuple is empty. Also return the number of faces found. """ faces = face_cascade.detectMultiScale(cv_gray) n_faces = len(faces) if n_faces == 0: cv_box = faces else: cv_box = tuple(faces[0]) return cv_box, len(faces)
def opencv_detect(image): """ Detects a face using OpenCV's cascade detector Returns a list of arrays containing (x, y, width, height) for each detected face. """ from cv2 import CascadeClassifier cc = CascadeClassifier('./bob/prepare_eyes_annotations/util/data/haarcascade_frontalface_alt.xml') faces = cc.detectMultiScale( image, 1.3, #scaleFactor (at each time the image is re-scaled) 4, #minNeighbors (around candidate to be retained) 0, #flags (normally, should be set to zero) (20,20), #(minSize, maxSize) (of detected objects on that scale) ) if(len(faces) == 0): faces = [[0,0,image.shape[0],image.shape[1]]] return faces
def __detect_face(cap: cv2.VideoCapture, cascade_classifier: cv2.CascadeClassifier) \ -> Tuple[np.array, Union[Tuple[None], BOUNDARY_BOX_TYPE]]: '''カメラから画像を取得し、顔部分の座標を取得する関数 Parameter ---------- cap: カメラから画像を取得するクラス cascade_classifier: 顔検出器 Returns ---------- 1. 取得画像 2. 以下の構造の顔座標データ 顔が検出された場合: ((顔1の座標x, 顔1の座標y, 顔1の横幅w, 顔1の縦幅), (顔2の座標x, 顔2の座標y, 顔2の横幅w, 顔2の縦幅), ...) 顔が検出されない場合: () ''' _, img = cap.read() faces = cascade_classifier.detectMultiScale(img) return img, faces
def detect_draw_rect_cascade(face_cascade: cv2.CascadeClassifier, frame: np.ndarray) -> np.ndarray: ''' Detect faces and draw rects on provided image ''' gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.resize(gray, (300, 300)) # Detect faces faces = face_cascade.detectMultiScale(gray, 1.1, 4) # Draw rectangle around the faces for (left, top, width, height) in faces: cv2.rectangle(frame, (left, top), (left + width, top + height), (255, 0, 0), 2) return frame
def classify(model, cascade_classifier_path_xml, transformations=None): cap = cv2.VideoCapture(0) face_cascade = CascadeClassifier(cascade_classifier_path_xml) while True: ret, img_bgr = cap.read() gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 2) for (x, y, w, h) in faces: w += 20 h += 20 r = max(w, h) / 2 centerx = x + w / 2 centery = y + h / 2 nx = int(centerx - r) ny = int(centery - r) nr = int(r * 2) faceimg_bgr = img_bgr[ny:ny + nr, nx:nx + nr] predimg = transformations(faceimg_bgr) predimg = np.expand_dims(predimg.numpy(), axis=0) outputs = model(torch.Tensor(predimg)) _, prediction = torch.max(outputs.data, 1) prediction = prediction.item() if prediction == 1: img_bgr = cv2.rectangle(img_bgr, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.putText(img_bgr, 'No Mask', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2) elif prediction == 0: img_bgr = cv2.rectangle(img_bgr, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(img_bgr, 'Mask', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) cv2.namedWindow("img_1") cv2.imshow('img_1', img_bgr) k = cv2.waitKey(30) & 0xff if k == 27: break cap.release() cv2.destroyAllWindows()
def detect_face_cv2(img): # load the photograph pixels = imread(img) # load the pre-trained model classifier = CascadeClassifier('haarcascade_frontalface_default.xml') # perform face detection bboxes = classifier.detectMultiScale(pixels, scaleFactor=1.05, minNeighbors=8 ) # print bounding box for each detected face for box in bboxes: x, y, width, height = box x2, y2 = x + width, y + height rectangle(pixels, (x, y), (x2, y2), (0, 0, 255), 1) imshow("face detection", pixels) waitKey(0) destroyAllWindows()
def face_detection(path): # Create the haar cascade faceCascade = CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # Read the image image = cv2.imread(path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Detect faces in the image faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) # Draw a rectangle around the faces for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) return len(faces), image
def camera_prediction(model): frequency = 0.02 # minutes instant = -1 faceCascade = CascadeClassifier('haarcascade_frontalface_alt.xml') capture = VideoCapture(0) while True: ret, frame = capture.read() image = copy.deepcopy(frame) gray = cvtColor(frame, COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(image_width, image_height), flags=CASCADE_SCALE_IMAGE) captured_face = None for (x, y, w, h) in faces: rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) captured_face = gray[y:y + h, x:x + w] imshow('Face detector', frame) if captured_face is not None: captured_face = resize(captured_face, (image_width, image_height)) instant = classify_emotion(model, captured_face, instant, frequency) captured_face = None if waitKey(1) & 0xFF == ord('q'): break video_capture.release() destroyAllWindows()
def opencv_detect(image): """ Detects a face using OpenCV's cascade detector Returns a list of arrays containing (x, y, width, height) for each detected face. """ from cv2 import CascadeClassifier cc = CascadeClassifier( './bob/prepare_eyes_annotations/util/data/haarcascade_frontalface_alt.xml' ) faces = cc.detectMultiScale( image, 1.3, #scaleFactor (at each time the image is re-scaled) 4, #minNeighbors (around candidate to be retained) 0, #flags (normally, should be set to zero) (20, 20), #(minSize, maxSize) (of detected objects on that scale) ) if (len(faces) == 0): faces = [[0, 0, image.shape[0], image.shape[1]]] return faces
def cropFace(img_path): img = cv2.imread(img_path) # load the photograph # pixels = img pixels = img # load the pre-trained model classifier = CascadeClassifier('haarcascade_frontalface_default.xml') # perform face detection bboxes = classifier.detectMultiScale(pixels) if len(bboxes) == 0: print("ERROR: No faces found.") return None # extract x, y, width, height = bboxes[0] x2, y2 = x + width, y + height BUFFER = int(width * 0.25) images = [] # show the image for i in range(len(bboxes)): x, y, width, height = bboxes[i] x2, y2 = x + width, y + height images.append( pixels[max(y - BUFFER, 0):min(y2 + BUFFER, pixels.shape[0]), max(x - BUFFER, 0):min(x2 + BUFFER, pixels.shape[1])]) # imshow('hehe', images[i]) # waitKey(0) images[i] = cv2.cvtColor(images[i], cv2.COLOR_BGR2RGB) return images
def facechop( image: Path, output_dir: Path, face_classifier: cv2.CascadeClassifier = FACE_CLASSIFIER, cv2_cascade_min_neighbors: int = 5) -> Generator[Path, None, None]: if not image.is_file(): raise FileNotFoundError(image) log = simple_logger("imgserve.facechop") img = cv2.imread(str(image)) if img is None: raise NotAnImageError(f"file exists, but is not an image.") minisize = (img.shape[1], img.shape[0]) miniframe = cv2.resize(img, minisize) faces = face_classifier.detectMultiScale( miniframe, minNeighbors=cv2_cascade_min_neighbors) count = 0 padding_pct = 0.2 for f in faces: x, y, w, h = [v for v in f] padding = int(h * padding_pct) cv2.rectangle(img, (x, y), (x + w + padding, y + h + padding), (255, 255, 255)) sub_face = img[y:y + h, x:x + w] output_dir.mkdir(exist_ok=True, parents=True) cropped_face_image: Path = output_dir.joinpath( image.stem + f"-{count}").with_suffix(".jpg") log.debug(f"writing {cropped_face_image}") cv2.imwrite(str(cropped_face_image), scale_image(sub_face)) yield cropped_face_image count += 1
def get_cropped_faces( image, y_plus=0, x_plus=0, face_cascade: cv2.CascadeClassifier = FACE_CASCADES['default']): """ A better version of getting the cropped face. It will return the several faces :param image: an image, numpy ndarray :param y_plus: margin of y :param x_plus: margin of x :param face_cascade: a face cascade classifier. The default value is default haarcascade XML file :return: cropped faces, (x, y, w, h) """ image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) d = face_cascade.detectMultiScale(image_gray, 1.3, 5) try: for x, y, w, h in d: crop = image_gray[y - y_plus:y + h + y_plus, x - x_plus:x + w + x_plus] return crop, (x, y, w, h) except Exception as e: print("Err: ", str(e)) return 0, (0, 0, 0, 0)
def get_cropped_face( image, y_plus=0, x_plus=0, face_cascade: cv2.CascadeClassifier = FACE_CASCADES['default']): """ A method to crop a (first) detected face from an image using face cascade classifier from OpenCV :param image: an image, numpy ndarray :param y_plus: margin of y :param x_plus: margin of x :param face_cascade: a face cascade classifier. The default value is default haarcascade XML file :return: cropped face, (x, y, w, h) """ image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) d = face_cascade.detectMultiScale(image_gray, 1.3, 5) try: [[x, y, w, h]] = d[0] crop = image_gray[y - y_plus:y + h + y_plus, x - x_plus:x + w + x_plus] return crop, (x, y, w, h) except Exception as e: print("Err: ", str(e)) return None, (0, 0, 0, 0)
class Tracker(object): """ A class that takes an input stream of image frames and attempts to detect and track any faces within those frames. """ def __init__(self): # create classifier to determine what a face is self.face_cascade = CascadeClassifier( "../data/haarcascades/haarcascade_frontalface_default.xml") self.trackers = [] # object tracker for each face self.tracking_count = 0 def detect_and_track(self, frame): """ Detect a face within a frame and pass off to tracking. :param frame: current frame to detect faces in :return: the count of faces detected in the frame """ detected_faces = self.face_cascade.detectMultiScale(frame, 1.3, 5) for (x, y, w, h) in detected_faces: # attempt to track the face if it is # not already being tracked self.track(x, y, w, h, frame) return self.tracking_count def track(self, x, y, w, h, frame): """ Attempt to track a face detected in a frame :param x: the x coordinate of the detected face :param y: the y coordinate of the detected face :param w: the width of the detected face :param h: the height of the detected face :param frame: the frame the face was detected in """ x_c = x + (w // 2) # x-coord of center point y_c = y + (h // 2) # y-coord of center point # see if the detected face coordinates are # close to one of the faces we are already # tracking matched = False i = 0 while not matched and i < len(self.trackers): curr_tracker = self.trackers[i] position = curr_tracker.get_position() # coordinates for tracked face `t` # must cast to int() for dlib x_t = int(position.left()) y_t = int(position.top()) w_t = int(position.width()) h_t = int(position.height()) x_t_c = x_t + (w_t / 2) # x-coord of center point y_t_c = y_t + (h_t / 2) # y-coord of center point # boolean values to check if the detected face is # inside of any of the faces we are already tracking, # and vis versa. x_c_inside_tracked = x_t <= x_c <= x_t + w_t y_c_inside_tracked = y_t <= y_c <= y_t + h_t x_t_c_inside_detected = x <= x_t_c <= x + w y_t_c_inside_detected = y <= y_t_c <= y + h # check if this face matches any faces we have been tracking matched = all([ x_c_inside_tracked, y_c_inside_tracked, x_t_c_inside_detected, y_t_c_inside_detected ]) i += 1 if not matched: # not matched face, start tracking the detected face new_tracker = dlib.correlation_tracker() new_tracker.start_track( frame, dlib.rectangle(int(x), int(y), int(x + w), int(y + h))) self.trackers.append(new_tracker) self.tracking_count += 1 def update(self, frame): """ Update the list of trackers with a new frame :param frame: the current frame to update the trackers with """ # remove any bad quality trackers self.trackers = [t for t in self.trackers if t.update(frame) >= 7] self.tracking_count = len(self.trackers) def get_coordinates(self): """ Get the x, y, w, h coordinates for a rectangle around each currently tracked face :return: a list of tuples (x, y, w, h) for a face """ positions = [] for t in self.trackers: p = t.get_position() positions.append( (int(p.left()), int(p.top()), int(p.width()), int(p.height()))) return positions @staticmethod def crop_face(img): """ Given an image with a single face, crop the face out and return it. :param img: :return: """ # get face classifier face_cascade = CascadeClassifier( "../data/haarcascades/haarcascade_frontalface_default.xml") # detect all faces detected = face_cascade.detectMultiScale(img, 1.2, 5) # get first face detected (probably the largest one) (x, y, w, h) = detected[0] # return cropped image return img[y:y + w, x:x + h]
exit() #Get the file paths to read from detector_output_files = directory_paths(test_annotation_dir) #Open all the files and read the JSON annotation_files = batch_open_deserialise(detector_output_files) #For each of the hand marked test files for annotation_file in annotation_files: #Read the image corresponding to the annotation img = imread(fix_path(annotation_file['imagePath'])) print "detecting... " classifier_output = cascade.detectMultiScale(img, minNeighbors=3, minSize=(175, 175), #Constrain scale within a range around training scale maxSize=(225, 225)) #Run the detector total_detections = len(classifier_output) fp = 0 tp = 0 #Open all the files and read the JSON golgi_polygons = annotation_file['shapes'] for golgi_polygon in golgi_polygons: #Make the list of points into a Shapely Polygon object golgi_polygon_shape = Polygon(golgi_polygon['points']) for detected_rect in classifier_output: (x1, y1, w, h) = detected_rect
from cv2 import CascadeClassifier from cv2 import imread from cv2 import rectangle from cv2 import imshow from cv2 import waitKey from cv2 import destroyAllWindows #print(cv2.__version__) #Cargamos un modelo pre-entrenado para reconocimiento facial y creamos un modelo en cascada con el classifier = CascadeClassifier('haarcascade_frontalface_default.xml') #cargamos una foto de prueba pixels = imread('image/foto grupal.jpg') #realizamos el reconocimiento facial. 1.1 significa ampliar la foto un 10% y 3 indica el nivel de fiabilidad de la deteccion bboxes = classifier.detectMultiScale(pixels, 1.1, 3) #representamos los cuadros delimitadores de los rostros detectados for box in bboxes: print(box) # para mostrar la imagen original con los cuadros delimitadores dibujados encima haremos lo siguiente: # extraemos cada propiedad del resultado (x e y de la esquina inferior izq del cuadro delimitador y su altura y anchura) x, y, width, height = box x2, y2 = x + width, y + height # dibujamos un rectangulo sobre los pixels rectangle(pixels, (x, y), (x2, y2), (0, 0, 255), 1) #imprimimos la imagen con la deteccion y la mantenamos abierta hasta que el usuario pulse una tecla #mostramos la imagen imshow('face detection', pixels) #mantenemos la ventana abierta hasta que se pulse una tecla waitKey(0)
import urllib import pylab import numpy from cv2.cv import * from cv2 import CascadeClassifier, waitKey, imread, imshow, cvtColor, equalizeHist, rectangle, Sobel, GaussianBlur face_cascade_name = "haarcascade_frontalface_alt.xml"; eyes_cascade_name = "haarcascade_eye.xml"; face_cascade = CascadeClassifier(face_cascade_name) eyes_cascade = CascadeClassifier(eyes_cascade_name) image = imread("jaxons_class_crop.jpg") colour_image = image image = cvtColor(image, CV_BGR2GRAY) image = equalizeHist(image) objects = face_cascade.detectMultiScale(image, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, (30, 30)) for x, y, w, h in objects: rectangle(image, (x, y), (x+w, y+h), (255, 255, 255)) face_image = image[y:y+h,x:x+w] imshow("Image", image) waitKey(0)
class FaceDetector(object): """Face Detector Face detection by Haar Feature-based Cascade Classifier in OpenCV. Attributes: ccc: Cascade Classifier """ @staticmethod def get_abs_path(file_name='haarcascade.xml'): """Return absolute path for given file name under data directory.""" return abspath(join(__file__, pardir, pardir, 'data', file_name)) @staticmethod def download_haarcascade_xml(save_path=None): """Download haar cascade file and save into given path.""" if not save_path: save_path = FaceDetector.get_abs_path() xml_url = ('https://raw.githubusercontent.com/opencv/opencv/master' '/data/haarcascades/haarcascade_frontalface_default.xml') xml_doc = urlopen(xml_url).read().decode('utf-8') with open(save_path, 'w') as xml: xml.write(xml_doc) def __init__(self, file_path=None): """Init Haar Cascade Classifier Create classifier instance with given XML file. Download XML from the web if the file does not exist. Args: file_path: the path for cascade classifier XML file """ if not file_path: file_path = FaceDetector.get_abs_path() if not exists(file_path): FaceDetector.download_haarcascade_xml(file_path) self.ccc = CascadeClassifier(file_path) def get_faces_pos(self, img, minNeighbors=3): """Get the position for each detected face. Call detectMultiScale function in CascadeClassifier and get detection result. Args: img: Matrix of the type CV_8U containing an image where face is detected minNeighbors: Parameter specifying how many neighbors each candidate rectangle should have to retain it Returns: numpy.ndarray contains position information for each detected face. For each position information, it has (x, y, w, h), where: x - the minimum horizontal coordinate of the image position. y - the minimum ordinate of the image position. w - Image width. h - Image height. """ return self.ccc.detectMultiScale(img, minNeighbors=minNeighbors) def get_faces_img(self, img, fpos=None, minNeighbors=3): """Get Images for each detected face. Crop face images from the original image. If face position is not given, use get_faces_pos to detect it first. Args: img: Matrix of the type CV_8U containing an image where the face is detected fpos: numpy.ndarray contains position information for each detected face minNeighbors: Parameter specifying how many neighbors each candidate rectangle should have to retain it (Use only when fpos is not given) Returns: A tuple contains cropped face images. """ if not fpos: fpos = self.get_faces_pos(img, minNeighbors=minNeighbors) faces = [img[y:y + h, x:x + w] for (x, y, w, h) in fpos] return tuple(faces)
def detect_human_face(): # 得到user目录下的所有文件名称,即各个好友头像 pics = listdir('image') # 使用人脸的头像个数 count_face_image = 0 # 存储使用人脸的头像的文件名 list_name_face_image = [] # 加载人脸识别模型 face_cascade = CascadeClassifier( 'model/haarcascade_frontalface_default.xml') for index, file_name in enumerate(pics): print(u'正在进行人脸识别,进度%d/%d,请耐心等待……' % (index + 1, len(pics))) # 读取图片 img = imread('image/' + file_name) # 检测图片是否读取成功,失败则跳过 if img is None: continue # 对图片进行灰度处理 gray = cvtColor(img, COLOR_BGR2GRAY) # 进行实际的人脸检测,传递参数是scaleFactor和minNeighbor,分别表示人脸检测过程中每次迭代时图 faces = face_cascade.detectMultiScale(gray, 1.3, 5) if (len(faces) > 0): count_face_image += 1 list_name_face_image.append(file_name) print(u'使用人脸的头像%d/%d' % (count_face_image, len(pics))) # 开始拼接使用人脸的头像 pics = list_name_face_image numPic = len(pics) eachsize = int(math.sqrt(float(640 * 640) / numPic)) # 先圈定每个正方形小头像的边长,如果嫌小可以加大 numrow = int(640 / eachsize) numcol = int(numPic / numrow) # 向下取整 toImage = Image.new('RGB', (eachsize * numrow, eachsize * numcol)) # 先生成头像集模板 x = 0 # 小头像拼接时的左上角横坐标 y = 0 # 小头像拼接时的左上角纵坐标 for index, i in enumerate(pics): print(u'正在拼接使用人脸的微信好友头像数据,进度%d/%d,请耐心等待……' % (index + 1, len(pics))) try: # 打开图片 img = Image.open('image/' + i) except IOError: print(u'Error: 没有找到文件或读取文件失败') else: # 缩小图片 img = img.resize((eachsize, eachsize), Image.ANTIALIAS) # 拼接图片 toImage.paste(img, (x * eachsize, y * eachsize)) x += 1 if x == numrow: x = 0 y += 1 toImage.save('data/使用人脸的拼接' + ".jpg") # 生成一个网页 with open('data/使用人脸的微信好友头像拼接图.html', 'w', encoding='utf-8') as f: data = ''' <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> <meta charset="utf-8" /> <title>使用人脸的微信好友头像拼接图</title> </head> <body> <p><font size=4px><strong>描述内容</strong></font></p> <img src="使用人脸的拼接.jpg" /> </body> </html> ''' data = data.replace( '描述内容', '在{}个好友中,有{}个好友使用真实的人脸作为头像'.format(len(friends), count_face_image)) f.write(data)