Ejemplo n.º 1
0
def get_neighbours(point_map, p, shape):

    i = util.R(p.x)
    j = util.R(p.y)

    if i < 0 or j < 0 or i >= shape[0] or j >= shape[1]: return []

    neighbours = []
    neighbours.extend(point_map[(i, j)])
    if j != shape[1] - 1: neighbours.extend(point_map[(i, j + 1)])
    if j != 0: neighbours.extend(point_map[(i, j - 1)])

    if i != shape[0] - 1: neighbours.extend(point_map[(i + 1, j)])
    if i != shape[0] - 1 and j != shape[1] - 1:
        neighbours.extend(point_map[(i + 1, j + 1)])
    if i != shape[0] - 1 and j != 0:
        neighbours.extend(point_map[(i + 1, j - 1)])

    if i != 0: neighbours.extend(point_map[(i - 1, j)])
    if i != 0 and j != shape[1] - 1:
        neighbours.extend(point_map[(i - 1, j + 1)])
    if i != 0 and j != 0: neighbours.extend(point_map[(i - 1, j - 1)])

    return neighbours
Ejemplo n.º 2
0
def get_cluster_points(f, img, shape, img_name, artist, dir="pixelClustering"):

    print("IMAGE SHAPE: (%s, %s)" % (shape[0], shape[1]))

    f.write("Speed factor: %f\n" % SPEED_FACTOR)
    f.write("Stopping Point: %f\n" % STOPPING_POINT)
    f.write("Min Speed: %f\n" % MIN_SPEED)
    f.write("Min Neighbours: %f\n" % MIN_NEIGHBOURS)
    f.write("Neighbourhood Radius: %f\n\n" % NBHD_RADIUS)

    blur = cv2.GaussianBlur(img, (7, 7), 1)
    util.display_img(blur, "Blurred", DISPLAY_IMG)
    sobelx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=5)
    sobely = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=5)

    scaled_x = cv2.convertScaleAbs(sobelx)
    scaled_y = cv2.convertScaleAbs(sobely)
    cv2.imwrite('%s/%s/%s/%s_sobelx.png' % (dir, artist, img_name, img_name),
                scaled_x)
    cv2.imwrite('%s/%s/%s/%s_sobely.png' % (dir, artist, img_name, img_name),
                scaled_y)

    moving_points, point_map = get_moving_pixels(f, img, sobelx, sobely)
    print("Number of moving points: %s" % len(moving_points))
    f.write("Initial number of moving points: %d\n" % len(moving_points))

    newImg = util.mapToImage(moving_points, img.shape)
    cv2.imwrite(
        '%s/%s/%s/%s_COLOR_%d.png' % (dir, artist, img_name, img_name, 1),
        newImg)
    #util.display_img(newImg, "Mapped from Point Set!", DISPLAY_IMG)

    # MOVEMENT PHASE

    start_time = time.time()
    movement_phase = True
    counter = 0
    while movement_phase:
        counter += 1

        bad_pix = []
        # movement phase
        for i in xrange(len(moving_points)):

            idx = (util.R(moving_points[i].x), util.R(moving_points[i].y))

            x_speed = getMinSpeed(SPEED_FACTOR * moving_points[i].gradx)
            y_speed = getMinSpeed(SPEED_FACTOR * moving_points[i].grady)

            if moving_points[i].stopped: continue
            moving_points[i].x = moving_points[i].x - x_speed
            moving_points[i].y = moving_points[i].y - y_speed

            idx2 = (util.R(moving_points[i].x), util.R(moving_points[i].y))

            # update space in bin
            if idx != idx2:
                point_map[idx].remove(moving_points[i])
                if idx2 in point_map:
                    point_map[idx2].append(moving_points[i])
                else:
                    print("BAD POINT FOUND: (%.3f, %.3f)" %
                          (moving_points[i].x, moving_points[i].y))
                    bad_pix.append(moving_points[i])

        for p in bad_pix:
            moving_points.remove(p)

        # evaluation phase
        for p in moving_points:
            stop = stop_pixel(point_map, p, shape)
            if stop:
                p.stopped = stop
        print("PHASE COMPLETE.")

        newImg2 = util.mapToImage_moving(moving_points, img.shape)
        cv2.imwrite(
            '%s/%s/%s/%s_COLOR_%d.png' % (dir, artist, img_name, img_name,
                                          (counter + 1)), newImg2)
        #util.display_img(newImg2, "Mapped from Point Set %s!" % (counter+1), DISPLAY_IMG

        # Determine whether to break the loop
        stp = get_percent_stopped_pixels(moving_points)
        print("Percentage stopped: %f" % stp)
        f.write("Rep %d. Percentage stopped: %f\n" % (counter, stp))
        if stp > STOPPING_POINT:
            print("STOPPING THE LOOP")
            movement_phase = False

    end_time = time.time()
    moving_points = clean_up(moving_points)
    f.write("\nTOTAL Number of iterations: %d\n" % counter)
    f.write("Time taken (in seconds): %f\n" % (end_time - start_time))
    f.write("Final number of moving points: %d\n" % len(moving_points))

    newImg2 = util.mapToImage(moving_points, img.shape)
    util.display_img(newImg2, "THE FINAL RESULT", DISPLAY_IMG)
    cv2.imwrite(
        '%s/%s/%s/%s_COLOR_%s.png' %
        (dir, artist, img_name, img_name, "FINAL"), newImg2)

    cv2.destroyAllWindows()

    calculate_local_stroke_thickness(f, point_map, moving_points, shape)

    util.save_point_set("%s.txt" % img_name, artist, "pointSet", moving_points)

    return moving_points
Ejemplo n.º 3
0
def train():

    # define model, dataloader, 3dmm eigenvectors, optimization method
    model = densenet
    model.load_state_dict(torch.load("model/chkpoint_000.pt"))
    model.cuda()
    #optimizer2 = torch.optim.Adam(model.parameters(),lr=1e-4)

    adjustmentnet.load_state_dict(torch.load("model/chkpoint_adj_000.pt"))
    adjustmentnet.cuda()
    adjustmentnet.train()

    loader = dataloader.BatchLoader
    face3dmm = dataloader.Face3DMM()
    optimizer = torch.optim.Adam(list(adjustmentnet.parameters()) +
                                 list(model.parameters()),
                                 lr=1e-5)

    # main training loop
    for epoch in itertools.count():
        for i, batch in enumerate(loader):
            optimizer.zero_grad()
            x = batch['image'].cuda()
            y = batch['lm2d'].cuda()
            y_pred = model(x)
            batchsize = x.shape[0]

            alphas = y_pred[:, :199]
            betas = y_pred[:, 199:228]
            s = y_pred[:, 228]
            t = y_pred[:, 229:231]
            t = torch.tanh(t)
            r = y_pred[:, 231:235]
            r = torch.tanh(r) * (3.14 / 4)

            # apply 3DMM model from predicted parameters
            alpha_matrix = alphas.unsqueeze(2).expand(
                *alphas.size(), alphas.size(1)) * torch.eye(
                    alphas.size(1)).cuda()
            beta_matrix = betas.unsqueeze(2).expand(*betas.size(),
                                                    betas.size(1)) * torch.eye(
                                                        betas.size(1)).cuda()
            shape_cov = torch.bmm(
                torch.stack(batchsize * [face3dmm.shape_eigenvec]),
                alpha_matrix)
            exp_cov = torch.bmm(
                torch.stack(batchsize * [face3dmm.exp_eigenvec]), beta_matrix)
            shape_cov = shape_cov.sum(2)
            exp_cov = exp_cov.sum(2)

            # alignment
            shape = (face3dmm.mu_shape.unsqueeze(0) + shape_cov.view(
                (batchsize, 53215, 3))) + exp_cov.view((batchsize, 53215, 3))
            lm = shape[:, face3dmm.lm, :]
            R = util.R(r).cuda()
            scaledshape = s.unsqueeze(1).unsqueeze(1) * torch.bmm(lm, R)
            alignedshape = t.unsqueeze(1) + scaledshape[:, :, :2]

            # adjustment network applied onto the landmarks of 3dMM taking input image
            adjustment = torch.tanh(adjustmentnet(x).view(-1, 68, 2))
            pred = (alignedshape + adjustment) * 112 + 112
            gt = y * 112 + 112

            # weight update
            loss = torch.mean(torch.norm(gt - pred, p=2, dim=2))
            loss.backward()
            optimizer.step()

            gt = gt[0].cpu().data.numpy()
            pred = pred[0].cpu().data.numpy()
            sample = x[0].cpu().permute(1, 2, 0).data.numpy()
            sample = sample * 255
            util.viewLM(sample.astype(np.uint8), pred)
            #io.imsave(f"example_{i:04d}.png",sample)

            print(f"epoch/batch {epoch}/{i}  |   Loss: {loss:.4f}")

        print("saving!")
        torch.save(model.state_dict(), f"model/chkpoint_{epoch:03d}.pt")
        torch.save(adjustmentnet.state_dict(),
                   f"model/chkpoint_adj_{epoch:03d}.pt")
Ejemplo n.º 4
0
def train():

    # define model, dataloader, 3dmm eigenvectors, optimization method
    model = densenet
    model.cuda()
    adjustmentnet.cuda()
    loader = dataloader.BatchLoader
    face3dmm = dataloader.Face3DMM()
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)

    # main training loop
    for epoch in itertools.count():
        for i, batch in enumerate(loader):
            optimizer.zero_grad()
            x = batch['image'].cuda()
            y = batch['lm2d'].cuda()
            y_pred = model(x)
            batchsize = x.shape[0]

            alphas = y_pred[:, :199]
            betas = y_pred[:, 199:228]
            s = y_pred[:, 228]
            t = y_pred[:, 229:231]
            t = torch.tanh(t)
            r = y_pred[:, 231:235]
            r = torch.tanh(r) * (3.14 / 4)

            # apply 3DMM model from predicted parameters
            alpha_matrix = alphas.unsqueeze(2).expand(
                *alphas.size(), alphas.size(1)) * torch.eye(
                    alphas.size(1)).cuda()
            beta_matrix = betas.unsqueeze(2).expand(*betas.size(),
                                                    betas.size(1)) * torch.eye(
                                                        betas.size(1)).cuda()

            shape_cov = torch.bmm(
                torch.stack(batchsize * [face3dmm.shape_eigenvec]),
                alpha_matrix)
            exp_cov = torch.bmm(
                torch.stack(batchsize * [face3dmm.exp_eigenvec]), beta_matrix)
            shape_cov = shape_cov.sum(2)
            exp_cov = exp_cov.sum(2)

            # alignment
            shape = (face3dmm.mu_shape.unsqueeze(0) + shape_cov.view(
                (batchsize, 53215, 3))) + exp_cov.view((batchsize, 53215, 3))

            lm = shape[:, face3dmm.lm, :]
            R = util.R(r).cuda()
            scaledshape = s.unsqueeze(1).unsqueeze(1) * torch.bmm(lm, R)
            alignedshape = t.unsqueeze(1) + scaledshape[:, :, :2]

            # adjustment network applied onto the landmarks of 3dMM taking input image
            # adjustment = adjustmentnet(x).view(-1,68,2)

            # weight update
            loss = torch.mean(torch.abs(y - (alignedshape)))
            loss.backward()
            optimizer.step()

            print(f"epoch/batch {epoch}/{i}  |   Loss: {loss:.4f}")
        print("saving!")
        torch.save(model.state_dict(), f"model/chkpoint_{epoch:03d}.pt")
Ejemplo n.º 5
0
def extract_topology(f, moving_points, point_map, img, corners, artist,
                     img_name):

    # encode some constants
    f.write("SCALE FACTOR: %d\n" % SCALE_FACTOR)
    f.write("PRUNING RADIUS: %.4f\n" % PRUNING_RADIUS)

    G = create_cluster_graph(f, point_map, moving_points, img.shape)
    """ Compute Minimum Spanning Tree """

    start_time = time.time()
    mst = nx.minimum_spanning_tree(G)
    end_time = time.time()
    print("NUMBER OF MST NODES: %d" % mst.number_of_nodes())
    print("NUMBER OF MST EDGES: %d" % mst.number_of_edges())
    f.write("NUMBER OF MST NODES: %d\n" % mst.number_of_nodes())
    f.write("NUMBER OF MST EDGES: %d\n" % mst.number_of_edges())
    f.write("Time to compute mst (s): %s\n\n" % (end_time - start_time))

    newImg = util.mapToImage(mst.nodes(), img.shape)
    util.thicken_line(newImg)
    util.display_img(newImg, "Post MST", DISPLAY_IMG)
    cv2.imwrite(
        "topology/%s/%s/%s_CompleteGraph.jpg" % (artist, img_name, img_name),
        newImg)
    """ Iterative Pruning """

    f.write("--- ITERATIVE PRUNING ---\n")
    num_spc_pts = len(moving_points)
    prev_spc_pts = num_spc_pts  # avoid infinite loops
    streak_len = 0
    counter = 0
    endpoints = []
    junctions = []
    itr_pruning_start = time.time()
    while num_spc_pts >= len(moving_points) // SCALE_FACTOR:

        counter += 1
        leaf_nodes = [x for x in mst.nodes_iter() if mst.degree(x) == 1]

        for leaf in leaf_nodes:
            total_weight = 0
            curr_node = leaf
            while total_weight < max(PRUNING_RADIUS, curr_node.lsw):
                n = mst.neighbors(curr_node)
                if len(n) != 1: break  # used to be == 0
                e = mst.get_edge_data(curr_node, n[0])
                if total_weight + e['weight'] < max(PRUNING_RADIUS,
                                                    curr_node.lsw):
                    total_weight += e['weight']
                    mst.remove_node(curr_node)
                    curr_node = n[0]
                else:
                    break

        print("NUM LEAF NODES: %d" % len(leaf_nodes))
        print("NUMBER OF PRUNED MST NODES: %d" % mst.number_of_nodes())
        print("NUMBER OF PRUNED MST EDGES: %d" % mst.number_of_edges())

        endpoints = [x for x in mst.nodes_iter() if mst.degree(x) == 1]
        junctions = [x for x in mst.nodes_iter() if mst.degree(x) >= 3]

        num_spc_pts = len(endpoints) + len(junctions)
        print("REP %d: %d points, %d special points" %
              (counter, len(moving_points), num_spc_pts))
        f.write("REP %d: %d points, %d special points\n" %
                (counter, len(moving_points), num_spc_pts))

        mstImg = util.mapToImage(mst.nodes(), img.shape)
        colorImg = mstImg.copy()
        colorImg = cv2.cvtColor(colorImg, cv2.COLOR_GRAY2BGR)

        for endpoint in endpoints:
            cv2.circle(colorImg, (util.R(endpoint.y), util.R(endpoint.x)), 3,
                       (0, 0, 255), -1)

        for junction in junctions:
            cv2.circle(colorImg, (util.R(junction.y), util.R(junction.x)), 3,
                       (255, 0, 0), -1)

        util.display_img(colorImg, "Post MST Pruning %d" % counter,
                         DISPLAY_IMG)
        cv2.imwrite(
            "topology/%s/%s/%s_Pruned_%d.jpg" %
            (artist, img_name, img_name, counter), colorImg)

        # AVOID INFINITE LOOPS
        if prev_spc_pts == num_spc_pts:
            if streak_len < 2:
                prev_spc_pts = num_spc_pts
                streak_len += 1
            else:
                break
        else:
            prev_spc_pts = num_spc_pts

    itr_pruning_end = time.time()
    print("\n--- FINAL POINTSET ---")
    print("%d points, %d special points\n" %
          (len(moving_points), (len(endpoints) + len(junctions))))
    f.write("\n--- FINAL POINTSET ---\n")
    f.write("%d points, %d special points\n" %
            (len(moving_points), (len(endpoints) + len(junctions))))
    f.write("Pruning time (in s): %s\n\n" %
            (itr_pruning_end - itr_pruning_start))

    mstImg = util.mapToImage(mst.nodes(), img.shape)
    colorImg = mstImg.copy()
    colorImg = cv2.cvtColor(colorImg, cv2.COLOR_GRAY2BGR)

    for corner in corners:
        x, y = corner.ravel()
        cv2.circle(colorImg, (x, y), 3, (0, 255, 0), -1)

    cv2.imwrite(
        "topology/%s/%s/%s_CORNERS_mst.jpg" % (artist, img_name, img_name),
        colorImg)

    f.write("NUMBER OF Connected Components: %d\n" %
            nx.number_connected_components(mst))

    loner_nodes = [x for x in mst.nodes_iter() if mst.degree(x) == 0]
    mst.remove_nodes_from(loner_nodes)
    mst.remove_nodes_from(endpoints)
    mst.remove_nodes_from(junctions)

    junction_endpoints = endpoints + junctions
    all_pairs = np.transpose([
        np.tile(junction_endpoints, len(junction_endpoints)),
        np.repeat(junction_endpoints, len(junction_endpoints))
    ])
    print("Number of pairs: %d" % len(all_pairs))
    f.write("Number of endpoint-junction pairs: %d\n" % len(all_pairs))

    print("NUMBER OF CC's: %d" % nx.number_connected_components(mst))
    f.write("NEW NUMBER OF Connected Components: %d\n" %
            nx.number_connected_components(mst))
    components_subgraphs = nx.connected_component_subgraphs(mst)
    point_pairs = []
    counter = 0
    cc_start_time = time.time()
    for comp in components_subgraphs:
        counter += 1
        endpoints = [x for x in comp.nodes_iter() if comp.degree(x) == 1]
        if len(endpoints) != 2: continue

        min_dist = 1000
        pair = []
        for p0, p1 in all_pairs:
            dist1 = util.pointDist(p0, endpoints[0]) + util.pointDist(
                p1, endpoints[1])
            dist2 = util.pointDist(p0, endpoints[1]) + util.pointDist(
                p1, endpoints[0])
            if dist1 < min_dist:
                min_dist = dist1
                pair = (p0, p1)
            if dist2 < min_dist:
                min_dist = dist2
                pair = (p1, p0)
        point_pairs.append(pair)

        testImg = img.copy()
        testImg = cv2.cvtColor(testImg, cv2.COLOR_GRAY2BGR)
        for node in comp.nodes_iter():
            cv2.circle(testImg, (util.R(node.y), util.R(node.x)), 3,
                       (0, 255, 0), -1)
        cv2.circle(testImg, (util.R(pair[0].y), util.R(pair[0].x)), 3,
                   (0, 0, 255), -1)
        cv2.circle(testImg, (util.R(pair[1].y), util.R(pair[1].x)), 3,
                   (0, 0, 255), -1)
        util.display_img(testImg, "Test", False)
        if len(comp.nodes()) > MIN_NODES_DETECTED:
            cv2.imwrite(
                "topology/%s/%s/%s_DetectedCurve_%d.jpg" %
                (artist, img_name, img_name, counter), testImg)

    cc_end_time = time.time()
    print("NUMBER OF POINT PAIRS: %d\n" % len(point_pairs))
    f.write("NUMBER OF POINT PAIRS: %d\n" % len(point_pairs))
    f.write("Time to Find Point Pairs (in s): %s\n\n" %
            (cc_end_time - cc_start_time))
    util.save_buddy_points("%s.txt" % img_name, artist, "buddyPoints",
                           point_pairs)

    f.write(" --- Calculating Paths --- \n")

    curves = []
    counter = 0
    curve_start = time.time()
    for pair in point_pairs:
        counter += 1
        path = nx.dijkstra_path(G, pair[0], pair[1])

        curves.append(path)
        print("Length of path: %d" % len(path))
        f.write("Length of path: %d\n" % len(path))

        testImg = img.copy()
        testImg = cv2.cvtColor(testImg, cv2.COLOR_GRAY2BGR)
        for node in path:
            cv2.circle(testImg, (util.R(node.y), util.R(node.x)), 3,
                       (0, 0, 255), -1)
        util.display_img(testImg, "Test", False)
        if len(path) > MIN_NODES_ACTUAL:
            cv2.imwrite(
                "topology/%s/%s/%s_ActualCurve_%d.jpg" %
                (artist, img_name, img_name, counter), testImg)

    curve_end = time.time()
    util.save_curves("%s.txt" % img_name, artist, "curves", curves)
    f.write("\nTime to Seperate Curves (in s): %s\n\n" %
            (curve_end - curve_start))
Ejemplo n.º 6
0
    alpha_matrix = alphas.unsqueeze(2).expand(
        *alphas.size(), alphas.size(1)) * torch.eye(alphas.size(1)).cuda()
    beta_matrix = betas.unsqueeze(2).expand(
        *betas.size(), betas.size(1)) * torch.eye(betas.size(1)).cuda()
    shape_cov = torch.bmm(torch.stack(batchsize * [face3dmm.shape_eigenvec]),
                          alpha_matrix)
    exp_cov = torch.bmm(torch.stack(batchsize * [face3dmm.exp_eigenvec]),
                        beta_matrix)
    shape_cov = shape_cov.sum(2)
    exp_cov = exp_cov.sum(2)

    # alignment
    shape = (face3dmm.mu_shape.unsqueeze(0) + shape_cov.view(
        (batchsize, 53215, 3))) + exp_cov.view((batchsize, 53215, 3))
    lm = shape[:, face3dmm.lm, :]
    R = util.R(r).cuda()
    scaledshape = s.unsqueeze(1).unsqueeze(1) * torch.bmm(lm, R)
    alignedshape = t.unsqueeze(1) + scaledshape[:, :, :2]

    # adjustment network applied onto the landmarks of 3dMM taking input image
    adjustment = torch.tanh(adjustmentnet(x).view(-1, 68, 2))
    pred = adjustment * 112 + 112
    gt = y * 112 + 112

    # weight update
    gt = gt[0].cpu().data.numpy()
    pred = pred[0].cpu().data.numpy()

    le = gt[36, :]
    re = gt[45, :]
    d = np.linalg.norm(le - re)