예제 #1
0
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
예제 #2
0
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
예제 #3
0
    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]
예제 #4
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]
예제 #5
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)
예제 #6
0
    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
예제 #7
0
 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)