def label_blobs_with_similar_angles(img, horz, vert, angle_threshold): labels = np.zeros(img.shape, dtype='uint32') dotprod_angle_thresh = cos(angle_threshold*pi/180) next_label = 1 area = get_rect(img) for r in range(img.shape[0]): for c in range(img.shape[1]): # skip already labeled pixels or background pixels if (labels[r][c] != 0 or img[r][c] == 0): continue labels[r][c] = next_label # now label all the connected neighbors of this point neighbors = [(c,r)] while len(neighbors) > 0: x,y = neighbors.pop() window = [(x-1,y-1), (x,y-1), (x+1,y-1), (x-1,y), (x+1,y), (x-1,y+1), (x,y+1), (x+1,y+1)] for xx,yy in window: # If this neighbor is in the image, not background, and not already labeled if (area.contains(xx,yy) and img[yy][xx]!=0 and labels[yy][xx]==0): dotprod = horz[y][x]*horz[yy][xx] + vert[y][x]*vert[yy][xx] # if the angle between these two vectors is less than angle_threshold degrees. if dotprod > dotprod_angle_thresh: labels[yy][xx] = next_label neighbors.append((xx,yy)) next_label += 1 return labels, next_label
def find_hough_boxes_simple(ht, hits): # convert hough coordinates into lines in original image lines = [ht.get_line(h) for h in hits] angle_thresh = 20 # in degrees def are_parallel(a,b): intersects_outside_image = not get_rect(ht).contains(intersect(a,b)) return angle_between_lines(a,b) < angle_thresh and intersects_outside_image # find all the parallel lines parallel = [] for i in range(len(lines)): for j in range(i+1,len(lines)): if are_parallel(lines[i], lines[j]): parallel.append((lines[i], lines[j], i, j)) def line_separation(a,b): center1 = (a.p1+a.p2)/2 center2 = (b.p1+b.p2)/2 return length(center1-center2) # sort the parallel line pairs so that lines that are most separated come first: parallel = sorted(parallel, key=lambda a : line_separation(a[0],a[1]), reverse=True) print("number of parallel line pairs: ", len(parallel)) boxes = [] area = get_rect(ht) # Now find boxes, these are pairs of parallel lines where all the intersecting points # are contained within the original image. for i in range(len(parallel)): for j in range(i+1,len(parallel)): l1,l3, idx1,idx3 = parallel[i] l2,l4, idx2,idx4 = parallel[j] c1 = intersect(l1,l2) c2 = intersect(l2,l3) c3 = intersect(l3,l4) c4 = intersect(l4,l1) # skip this pair if it's outside the image if (not area.contains(c1) or not area.contains(c2) or not area.contains(c3) or not area.contains(c4) ): continue polyarea = polygon_area([c1, c2, c3, c4]) boxes.append((c1,c2,c3,c4,polyarea,idx1,idx2,idx3,idx4)) boxes = sorted(boxes, key=lambda x : x[4], reverse=True) return boxes
def detect(self, image): """ Detects a face in an image """ rects = self.detector(image) if not len(rects): return dlib.get_rect(image) max_area = [None, 0] for rect in rects: if rect.area() > max_area[1]: max_area = [rect, rect.area()] return max_area[0]
def detect(self, image): """ Detects a face in an image :param image: numpy.ndarray of rank 3 containing an image from which to detect a face :return: dlib.rectangle containing the boundary box for the face in the image, or None on failure """ rects = self.detector(image) if not len(rects): return dlib.get_rect(image) max_area = [None, 0] for rect in rects: if rect.area() > max_area[1]: max_area = [rect, rect.area()] return max_area[0]
def perform_generic_hough_transform(self, img, record_hit): assert(img.shape[0] == self.size) assert(img.shape[1] == self.size) cent = center(get_rect(img)) even_size = self.size - (self.size%2) sqrt_2 = sqrt(2) for r in range(img.shape[0]): for c in range(img.shape[1]): val = img[r][c] if (val != 0): x = c - cent.x y = r - cent.y # Now draw the curve in Hough space for this image point for t in range(self.size): theta = t*pi/even_size radius = (x*cos(theta) + y*sin(theta))/sqrt_2 + even_size/2 + 0.5 rr = int(radius) record_hit(point(t,rr), point(c,r), val)
def detect_landmarks_for_loss(self, image): """ Function that returns Landmark coordinates for original Loss Layer :param image: <class 'numpy.ndarray'> with shape self.IMG_SHAPE :return: <class 'numpy.ndarray'> with shape (46, 2) """ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # detect landmarks and transform to image coordinates landmarks = self.predictor(gray, dlib.get_rect(gray)) shape = face_utils.shape_to_np(landmarks) # keep only 46 landmarks coords = np.array( [[ shape[17, :], shape[18, :], shape[19, :], shape[20, :], shape[21, :], # left brow shape[22, :], shape[23, :], shape[24, :], shape[25, :], shape[26, :], # right brow shape[36, :], shape[39, :], shape[42, :], shape[45, :], # left and right eye limits shape[27, :], shape[28, :], shape[29, :], shape[30, :], shape[31, :], shape[32, :], shape[33, :], shape[34, :], shape[35, :], # nose shape[48, :], shape[49, :], shape[50, :], shape[51, :], shape[52, :], shape[53, :], shape[54, :], shape[55, :], shape[56, :], shape[57, :], shape[58, :], shape[59, :], shape[61, :], shape[62, :], shape[63, :], shape[65, :], shape[66, :], shape[67, :], # mouth shape[6, :], shape[7, :], shape[8, :], shape[9, :], shape[10, :] # chin ]], dtype=np.int32) coords = np.squeeze(coords) return coords
def are_parallel(a,b): intersects_outside_image = not get_rect(ht).contains(intersect(a,b)) return angle_between_lines(a,b) < angle_thresh and intersects_outside_image
# Ask the detector to find the bounding boxes of each face. The 1 in the # second argument indicates that we should upsample the image 1 time. This # will make everything bigger and allow us to detect more faces. dets = detector(img, 1) #print("Number of faces detected: {}".format(len(dets))) if (len(dets) != 1): #input() fp.write("Processing file: {}\tNumber of faces detected: {}".format( f, len(dets))) # Now process each face we found. #for k, d in enumerate(dets): #print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format( # k, d.left(), d.top(), d.right(), d.bottom())) # Get the landmarks/parts for the face in box d. d = dlib.get_rect(img) shape = sp(img, d) # Draw the face landmarks on the screen so we can see what face is currently being processed. #win.clear_overlay() #win.add_overlay(d) #win.add_overlay(shape) # Compute the 128D vector that describes the face in img identified by # shape. In general, if two face descriptor vectors have a Euclidean # distance between them less than 0.6 then they are from the same # person, otherwise they are from different people. Here we just print # the vector to the screen. face_descriptor = facerec.compute_face_descriptor(img, shape) #print(face_descriptor)