Example #1
0
def render_lsd(seq):

    plypath = os.path.join(seq, 'render_me.ply')
    verts, edges = IO.read_ply(plypath)
    lsd_mesh = Mesh()
    lsd_mesh.verts = verts.astype(np.float32)

    campath = os.path.join(seq, 'render.py')
    Rs, ts = IO.import_blender_cam(campath)

    W, H = 1920, 1080
    im = empty((H, W, 3), np.uint8)
    cam = Geom.cam_params(29.97, W, H, 35)  # Blender defaults
    cam = cam.astype(np.float32)

    render_out = os.path.join(seq, 'render')
    Util.try_mkdir(render_out)

    im[:] = 255

    pts = lsd_mesh.project_verts(Rs[0].astype(np.float32), ts[0].astype(np.float32), cam)
    pt_buf = buffer_points(pts, np.r_[255, 82, 82], alpha=0.2, size=2)
    render_buffer(im, pt_buf, bg=255)

    out = os.path.join(render_out, 'frame_0.png')
    IO.imwrite(out, im)
Example #2
0
def show_edges(seq, cloud, thresh, min_score, imtype='png'):
    edge_dir = os.path.join(seq, 'edges', '*.' + imtype)
    paths = glob.glob(edge_dir)

    segout = os.path.join(seq, 'segment_stats.npz')
    # --- Load data ---
    npz = np.load(segout)
    score = npz['score']
    # total = npz['total']
    # curv_mean = npz['curv_mean']
    # curv_var = npz['curv_var']

    # --- Prepare data ---
    F = len(paths)

    fx, fy, cx, cy = cloud.cam
    labels = cloud.labels_frame

    focal = cloud.cam[:2]
    center = cloud.cam[2:]

    outfolder = os.path.join(seq, 'hard_edges')
    Util.try_mkdir(outfolder)

    # --- Do it ---
    print("Writing out frames...")

    j = 0
    for f in range(F):
        if f % 5:
            continue
        print("Frame {}".format(f))
        path = paths[f]
        im = IO.imread(path)
        col = color.gray2rgb(255 - im)

        s, e = cloud.frame_range[f]

        for i in range(s, e):
            if labels[i] == 0 or score[i] < min_score:
                continue

            line = empty(4)
            line[:2] = cloud.local_rays[i, :2] * focal + center
            line[2:] = cloud.local_rays[i + 1, :2] * focal + center
            np.round(line, out=line)
            I, J = Drawing.line(*(line.astype(int)))
            Drawing.draw_points(col, I, J, color=(255, 0, 0))
            Drawing.draw_points(col, I + 1, J, color=(255, 0, 0))
            Drawing.draw_points(col, I, J + 1, color=(255, 0, 0))
            # col[I, J] = 255, 0, 0

        out = os.path.join(outfolder, '{:04d}.png'.format(f))
        j += 1
        IO.imwrite(out, col)
Example #3
0
def render_buffer(im, buf, bg=1):
    '''
    Order by depth and mix alpha values at the same pixel

    buf: (Nx7) array with each element as [i, j, d, alpha, r, g, b]
    '''
    inds = Util.lex_order(buf[:, :3].T, maxs=(720, 1280, 20))[::-1]
    _render_buffer_jit(im, buf, inds, bg)
Example #4
0
def write_clusters(outdir, lookup, P1, P2, indmap):
    Util.try_mkdir(outdir)
    verts_all = []
    edges_all = []
    E = 0
    for key, cluster in lookup.items():
        # path = os.path.join(outdir, 'set_{}.ply'.format(key))

        inds = indmap[cluster]
        verts = np.vstack((P1[inds], P2[inds]))
        V = len(verts)
        edges1 = np.r_[0:V].reshape(2, -1).T
        edges2 = np.c_[np.r_[0:V - 1], np.r_[1:V]]
        edges = np.vstack((edges1, edges2))

        verts_all.append(verts)
        edges_all.append(edges + E)

        E += len(edges)

    path = os.path.join(outdir, '_full.ply')
    IO.save_point_cloud(path, np.vstack(verts_all), np.vstack(edges_all))
Example #5
0
def find_cluster_line3(deltas, rays, depths, init_support, res, thresh):
    '''
    Given a set of line segments, defined by (x1, y1) = p and (x2, y2) = p + u,
    locate clusters
    The segments are intersection points of ray segments.
    ray_angles are projected ray angles of camera ray angles.
    Depths are distance the segments intersect the center of the ray of interest
    '''
    N = rays.shape[1]
    if N == 0:
        return empty(0, np.int64), 100.0, 0.0, empty(0, depths.dtype), 0.0

    # Note: (ps, us, depths, frames) should be ordered by frames
    ray_angles = empty(N, depths.dtype)
    for i in range(N):
        iqy = 1 / rays[1, i]
        pos = (1 - rays[0, i]) * iqy
        neg = -(1 + rays[0, i]) * iqy
        if abs(pos) < abs(neg):
            ray_angles[i] = pos
        else:
            ray_angles[i] = neg

    dc = np.abs(ray_angles)

    for k in range(2):
        sel = np.where(dc <= init_support)[0]

        if len(sel) == 0:
            init_support += 0.02
            continue

        # Search for a "big enough" cluster of depths according to nearby cameras
        hist, histx = Util.histogram(depths[sel],
                                     bins=int(2 / res[1]),
                                     rng=(0, 2))
        i = hist.argmax()

        if hist[i] > 10:
            break
        init_support += 0.02

    else:
        return empty(0, np.int64), 100.0, 0.0, ray_angles, 0.0

    peak_depth = 0.5 * (histx[i] + histx[i + 1])
    sel = np.where(dc < init_support * 5)[0]
    depth, radius, inside, good = CircleRays.sequential_circle_space(
        depths[sel], ray_angles[sel], peak_depth, init_support, thresh[1])

    return sel[inside], radius, depth, ray_angles, len(inside) / len(sel)
Example #6
0
def find_contours_rgb(rgb, D, d_sigma=2, d_scale=1):
    from skimage.morphology import skeletonize
    # from skimage.filters import gaussian

    tim = Util.Timer()

    # grey = rgb2grey(rgb)
    grey = Image.rgb2grey(rgb)
    tim.add("Gray")
    edges_b = Image.find_edges(grey, sigma=2)
    tim.add("Find edges")

    edge_map = skeletonize(edges_b)
    tim.add("Skel")

    I, J = np.where(edge_map)
    N = len(I)

    P = empty((2, N), int)
    P[0] = J  # x
    P[1] = I  # y

    # Find normals based on depth
    # D_blur = gaussian(D, sigma=d_sigma)
    D_blur = D
    dgy, dgx = Image.gradient(D_blur)

    grey_blur = Image.gaussian(grey, sigma=2)
    gy, gx = Image.gradient(grey_blur)
    tim.add("Grad")

    normals = empty((2, N))
    normals[0] = gx[I, J]
    normals[1] = gy[I, J]
    normals /= norm(normals, axis=0)

    # Use depth map to make sure pointing correct way
    dnormals = zeros((2, N))
    dnormals[0] = dgx[I // d_scale, J // d_scale]
    dnormals[1] = dgy[I // d_scale, J // d_scale]
    mag = norm(dnormals, axis=0)
    sel = mag > 0
    dnormals[:, sel] /= mag[sel]

    flip = (normals * dnormals).sum(axis=0) > 0
    normals[:, flip] *= -1
    tim.add("The rest")
    # print(tim)

    return P.T, normals.T, edge_map
Example #7
0
def break_segments(pts, curvs, labels, max_breaks=10, max_curv=15e-3):
    '''
    Break segments (given by ordered labels) at points of high curvature.

    Note: A bit of magic in the choice of max_curv. It will depend on the
    support used when estimating the curvature. The discretization of pixesl
    means a smaller support will have more noise.

    In future, could use rate of change of normals along the line... Later.
    '''
    acurvs = np.abs(curvs)
    curv_smooth = Image.gaussian1d(acurvs, 2.0)
    peaks = Util.find_peaks(curv_smooth)
    corners = peaks[np.where(acurvs[peaks] > max_curv)[0]]

    newlabels = labels * max_breaks

    # Relabel
    N = len(newlabels)
    for j in corners:
        label = newlabels[j]
        newlabel = label + 1
        i = j
        while i < N and newlabels[i] == label:
            newlabels[i] = newlabel
            i += 1

    # Compress labels
    newlabel = 1
    i = 0
    while i < N:
        currentlabel = newlabels[i]
        j = i
        while j < N and newlabels[j] == currentlabel:
            newlabels[j] = newlabel
            j += 1

        i = j
        newlabel += 1

    return newlabels
Example #8
0
    def rays_near_point(self, p):
        # Convert to voxel coords:
        coords = (self.scale * (p - self.offset)).astype(np.int64)

        inds = empty(3 * 3 * 3, np.int64)
        n = 0
        # for di, dj, dk in ((0,0,0), (-1,0,0), (1,0,0), (0,-1,0), (0,1,0), (0,0,-1), (0,0,1)):
        for di in range(-1, 2):
            for dj in range(-1, 2):
                for dk in range(-1, 2):
                    c = coords.copy()
                    c[0] += di
                    c[1] += dj
                    c[2] += dk
                    ind = self.to_linear_ind(c)
                    if ind >= 0 and ind < self.N:
                        inds[n] = ind
                        n += 1
        # ind = self.to_linear_ind(coords)
        # if ind < 0 or ind >= self.N:
        #     return empty(0, np.int64)

        N = 0
        count = empty(n, np.int64)
        cumsum = empty(n + 1, np.int64)
        for i in range(n):
            ind = inds[i]
            count[i] = self.vox2ray_count[ind]
            cumsum[i] = N
            N += count[i]
        cumsum[-1] = N

        # N = self.vox2ray_count[ind]
        sel = empty(N, np.int64)
        for i in range(n):
            ind = inds[i]
            sel[cumsum[i]:cumsum[i + 1]] = self.vox2ray_inds[ind, :count[i]]
        # sel[:] = self.vox2ray_inds[ind, :N]

        return Util.unique(sel)
Example #9
0
    def load(self, data):
        total = 0
        jump = 0
        down = 0
        fail = 0
        for i in data:
            total += 1
            if self.found(i):
                jump += 1
                if self._cfgs["vmode"] == "full":
                    self.output(
                        str(total) + ".跳过:" + urllib.parse.urlparse(i).path)

                #continue
            else:
                if self._cfgs["vmode"] == "full":
                    self.output(
                        str(total) + ".[正在下载]:" +
                        urllib.parse.urlparse(i).path)

                try:
                    ua = Util.randUA()
                    req = urllib.request.Request(i, headers={"User-Agent": ua})
                    response = urllib.request.urlopen(req)
                except urllib.error.URLError as reason:
                    fail += 1
                    self.output("URLError:" + str(reason))
                except urllib.error.HTTPError as reason:
                    fail += 1
                    self.output("HTTPError:" + str(reason))
                else:
                    down += 1
                    img = response.read()
                    with open(self.fullpath(i), "wb") as f:
                        f.write(img)

        self.output("实时总数%s,跳过%s,下载%s,失败%s" % (total, jump, down, fail))
        return True
Example #10
0
#!/usr/bin/python3
#-*-coding:utf-8-*-


from tools import Util


'''
入口功能test
'''
#u = Util.Util()
#ua = u.getUA()
#print(ua)

print(Util.randUA())

if __name__ == "__main__":
    print("welcome")
Example #11
0
def render_animation(seq, sub, dopoly):
    import pynutmeg
    import time
    import os
    import RayCloud

    fig = pynutmeg.figure('cube', 'figs/imshow.qml')

    W, H = 1920, 1080
    im = empty((H, W, 3), np.uint8)
    cam = Geom.cam_params(29.97, W, H, 35)  # Blender defaults
    cam = cam.astype(np.float32)

    print("Loading data")
    cloud = RayCloud.load(os.path.join(seq, sub))

    datapath = os.path.join(seq, 'occlusion_data.npz')
    data = np.load(datapath)
    mesh_path = os.path.join(seq, 'occlusion_mesh.npz')
    occl_mesh = load_mesh(mesh_path)
    # occl_mesh = Mesh()
    # occl_mesh.verts = data['verts'].astype(np.float32)
    edges = data['edges'].astype(np.uint32)
    ply_path = os.path.join(seq, 'model.ply')
    if os.path.exists(ply_path):
        obj_mesh = from_ply(ply_path)
    else:
        obj_mesh = Mesh()

    if dopoly:
        poly_data = os.path.join(seq, sub, 'poly_data.npz')
        polynpz = np.load(poly_data)
        poly_mesh = Mesh()
        poly_mesh.verts = polynpz['verts'].astype(np.float32)
        poly_mesh.edges = polynpz['edges'].astype(np.uint32)
    else:
        poly_mesh = None

    # pers_mesh_path = os.path.join(seq, 'persistent_mesh.npz')
    # pers_mesh = load_mesh(pers_mesh_path)

    campath = os.path.join(seq, 'animation.py')
    Rs, ts = IO.import_blender_cam(campath)

    # Grab frame info
    inds = data['inds']
    frames = cloud.frames[inds]

    render_out = os.path.join(seq, 'animate')
    Util.try_mkdir(render_out)

    F = len(Rs)
    N = len(frames)

    print("Loaded", frames.max())

    end_frame = 0

    for f in range(0, F, 10):
        print("Frame:", f)
        # R = cloud.Rs[f]
        # t = cloud.ts[f]
        R = Rs[f].astype(np.float32)
        t = ts[f].astype(np.float32)

        while end_frame < N and frames[end_frame] < f:
            end_frame += 1

        occl_mesh.edges = edges[:end_frame]

        im[:] = 255
        if len(occl_mesh.edges) > 0:
            t0 = time.time()
            render_frame(im, obj_mesh, occl_mesh, None, R, t, cam)
            print("Render time: {} ms".format( int((time.time() - t0)*1000) ))

        # time.sleep(0.005)

        fig.set('ax.im', binary=im)
        out = os.path.join(render_out, 'frame_{:05d}.png'.format(f))
        IO.imwrite(out, im)
Example #12
0
def test_render_seq(seq, sub, dopoly):
    import pynutmeg
    import time
    import os
    import RayCloud

    fig = pynutmeg.figure('cube', 'figs/imshow.qml')

    W, H = 1920, 1080
    im = empty((H, W, 3), np.uint8)
    cam = Geom.cam_params(29.97, W, H, 35)  # Blender defaults
    cam = cam.astype(np.float32)

    print("Loading data")
    cloud = RayCloud.load(os.path.join(seq, sub))

    mesh_path = os.path.join(seq, 'occlusion_mesh.npz')
    occl_mesh = load_mesh(mesh_path)
    ply_path = os.path.join(seq, 'model.ply')
    if os.path.exists(ply_path):
        obj_mesh = from_ply(ply_path)
    else:
        obj_mesh = Mesh()

    if dopoly:
        poly_data = os.path.join(seq, sub, 'poly_data.npz')
        polynpz = np.load(poly_data)
        poly_mesh = Mesh()
        poly_mesh.verts = polynpz['verts'].astype(np.float32)
        poly_mesh.edges = polynpz['edges'].astype(np.uint32)
    else:
        poly_mesh = None

    pers_mesh_path = os.path.join(seq, 'persistent_mesh.npz')
    pers_mesh = load_mesh(pers_mesh_path)

    campath = os.path.join(seq, 'render.py')
    Rs, ts = IO.import_blender_cam(campath)

    render_out = os.path.join(seq, 'render')
    Util.try_mkdir(render_out)

    F = min(3, len(Rs))

    print("Loaded")

    for f in range(F):
        print("Frame:", f)
        # R = cloud.Rs[f]
        # t = cloud.ts[f]
        R = Rs[f].astype(np.float32)
        t = ts[f].astype(np.float32)

        im[:] = 255
        t0 = time.time()
        render_frame(im, obj_mesh, occl_mesh, None, R, t, cam)
        print("dt:", (time.time() - t0)*1000)

        # time.sleep(0.005)

        fig.set('ax.im', binary=im)
        out = os.path.join(render_out, 'frame_{}.png'.format(f))
        IO.imwrite(out, im)

        im[:] = 255
        t0 = time.time()
        render_frame(im, obj_mesh, pers_mesh, poly_mesh, R, t, cam, color=np.r_[255, 82, 82], poly_color=np.r_[0,0,0])
        print("dt:", (time.time() - t0)*1000)

        fig.set('ax.im', binary=im)
        out = os.path.join(render_out, 'frame_pers_{}.png'.format(f))
        IO.imwrite(out, im)
Example #13
0
def detect_loop(ray_inds, Cs, Qs, pluckers, planes, labels, frames, raygrid,
                config, score, total, curv_mean, m2, depths_out, radii_out,
                inlier_out, edge_angles_out, neighbors, status):
    '''
    score: Output, integer array classifying the type of each segment
    '''
    # Each valid segment is labelled with a non-zero label
    # tim = Util.LoopTimer()
    # loop_i = 0
    for ray_ind in ray_inds:
        # tim.loop_start(loop_i)
        # loop_i += 1

        if labels[ray_ind] == 0:
            status[ray_ind] = -1
            score[ray_ind] = 0
            continue

        # First find other segments that are nearby, and might overlap
        # The RayVoxel.Grid class offers very fast lookups at the cost of memory
        near_grid = raygrid.rays_near_ind(ray_ind)
        # tim.add("RayGrid Search")

        if len(near_grid) < 10:
            status[ray_ind] = -1
            continue

        # Filter frame support
        near = filter_frames(near_grid, frames, ray_ind, config.frame_support)
        # close_frames = np.abs(frames[near_grid] - frames[ray_ind]) <= config.frame_support
        # near = near_grid[close_frames]
        # tim.add("Filter frames")

        # Intersect the shortlisted segments with this segment
        # ps, us describe the intersection locations of the other segments'
        # start- and end-points.
        ps1, us, intersecting = find_intersections(Cs, Qs, pluckers, ray_ind,
                                                   planes, near)
        # print("Near:", len(near))
        # tim.add("Find intersections")
        if len(intersecting) < 10:
            status[ray_ind] = -1
            continue

        ray = 0.5 * (Qs[ray_ind] + Qs[ray_ind + 1])
        ray /= Geom.norm3(ray)
        plane = planes[ray_ind]
        normal = plane[:3]
        tangent = Geom.cross3(ray, normal)

        # Create rotation matrix to orthoganally project intersections
        # into plane of this segment. This plane is tangent to the edge
        R_tang = empty((2, 3), ps1.dtype)
        R_tang[0] = ray
        R_tang[1] = tangent

        center = Cs[ray_ind]
        ps2d = dot(R_tang, (ps1 - center).T)
        us2d = dot(R_tang, us.T)
        px, py = ps2d[0], ps2d[1]
        ux, uy = us2d[0], us2d[1]

        # Solve for the intersection with the center of the segment
        # [x, 0] = p + t*u
        uy[uy == 0] = 1e-10
        ts = -py / uy
        depths = px + ts * ux
        # Project the intersecting segments into the normal plane.
        # This plane's normal is roughly aligned with the edge direction.
        R_norm = empty((3, 3), ps1.dtype)
        R_norm[0] = ray
        R_norm[1] = normal
        R_norm[2] = tangent
        centers = dot(R_norm, (Cs[intersecting] - center).T)

        # plane_angles = np.arctan(centers[1]/centers[2])

        # Check where start and end points straddles center ray of this segment
        crossing = py * (py + uy) < 0
        good_depths = (depths > 0.2) & (depths < 1e6)
        # close_frames = np.abs(frames[intersecting] - frames[ray_ind]) <= config.frame_support
        # in_normal_plane = np.abs(plane_angles) <= config.planar_support

        sel = np.where(good_depths & crossing)[0]
        # sel = np.where(good_depths & crossing & (close_frames | in_normal_plane))[0]
        # tim.add("Intersect filter")
        # print("Sel:", len(sel))

        # We're looking for clusters of line segments in the tangent plane
        # These indicate a high likelihood of a persistent edge
        # frames = cloud.frames[ intersecting[sel] ]
        # p = ps2d[:,sel]
        u = us2d[:, sel]
        d = depths[sel]

        c_sel = centers[:, sel]
        rays = empty((2, len(sel)), centers.dtype)
        rays[0] = d - c_sel[0]
        rays[1] = -c_sel[1]

        rays /= CircleRays.norm_ax(rays, axis=0)
        # tim.add("Prepare clustering")

        dthresh = config.depth_thresh
        # Cluster based on circle space
        cluster_inds, radius, depth, dual_centers, dual_rays, inlier_frac = find_cluster_line4(
            c_sel, rays, depth_thresh=dthresh, percentile=config.inlier_thresh)

        # tim.add("Clustering")

        cluster_full = intersecting[sel[cluster_inds]]
        M = min(neighbors.shape[1], len(cluster_full))

        if inlier_frac > 0.02:
            if abs(radius) < config.min_radius:
                # Hard edge
                status[ray_ind] = 1
                score[ray_ind] += len(cluster_full)
            else:
                status[ray_ind] = 2
                score[ray_ind] += len(cluster_full)

            # Want to estimate the depths of the rays on either side of the segment
            u_cluster = u[:, cluster_inds]
            intersect_angles = np.arctan(-u_cluster[0] / u_cluster[1])
            # Zero is verticle
            alpha = np.median(intersect_angles)
            # Find angle between rays
            theta = 0.5 * arccos(dot(Qs[ray_ind], Qs[ray_ind + 1]))
            d1 = depth * sin(PI / 2 + alpha) / sin(PI / 2 - alpha - theta)
            d2 = depth * sin(PI / 2 - alpha) / sin(PI / 2 + alpha - theta)
            depths_out[ray_ind, 0] = d1
            depths_out[ray_ind, 1] = d2
            depths_out[ray_ind, 2] = depth

            # depths_out[ray_ind] = depth
            radii_out[ray_ind] = radius
            inlier_out[ray_ind] = inlier_frac
            edge_angles_out[ray_ind] = alpha

            ray_c = rays[:, cluster_inds]
            cluster_angles = np.abs(np.arctan(ray_c[1] / ray_c[0]))

            closest = Util.argsort(cluster_angles)
            neighbors[ray_ind, :M] = cluster_full[closest[:M]]

        else:
            status[ray_ind] = -1
            score[ray_ind] = 0
            labels[ray_ind] = 0
            continue