def paintParameterLine(parameterLine, width, height, img):
    #PAINTPARAMETERLINE Paint parameterized line
    #   parameterLine: [n1,n2,n3,planeID,u1,u2], first 3 dims are normal
    #   direction, 4th dim is the base plane ID for U (1=XY), 5-6th dims are U
    #   of start and end point.
    #   width, height: the size of output panorama, width = height x 2
    #   img: the image on which lines will be drawn. If no img,
    #   img=zeros(height,width).
    lines = parameterLine

    if img is None:
        panoEdgeC = np.zeros([height, width])
    else:
        img = np.double(img)
        panoEdgeC = imresize(img, [height, width])
        if img.shape[2] == 3:

            pimg = PIL.Image.fromarray(np.uint8(panoEdgeC))
            panoEdgeC = pimg.convert('L')

            panoEdgeC = np.array(panoEdgeC) * 0.5

    # valid = true(size(lines,1),1);
    # uv_vp = xyz2vp([vp;-vp]);
    # vpm = min(floor( (uv_vp(:,1)-(-pi)) /(2*pi)*width)+1, width);
    # vpn = min(floor( ((pi/2)-uv_vp(:,2))/(pi)*height )+1, height);
    # valid = lines(:,4)==1;
    # lines = lines(~valid,:); #horizontal
    # lines = lines(valid,:); #vertical
    num_sample = max(height, width)
    for i in np.arange(lines.shape[0]):
        #     fprintf('#d\n',i);
        n = lines[i, 0:3]
        sid = lines[i, 4] * 2 * np.pi
        eid = lines[i, 5] * 2 * np.pi
        if eid < sid:
            x = np.linspace(sid, eid + 2 * np.pi, num_sample)
            x = x % (2 * np.pi)
    #         x = sid-1:(eid-1+numBins);
    #         x = rem(x,numBins) + 1;
        else:
            x = np.linspace(sid, eid, num_sample)

    #     u = -pi + (x'-1)*uBinSize + uBinSize/2;
        u = -np.pi + x.T
        v = CoordsTransform.computeUVN(n, u, lines[i, 3])
        xyz = CoordsTransform.uv2xyzN(np.column_stack((u, v)), lines[i, 3])
        uv = CoordsTransform.xyz2uvN(xyz, 0)

        uv = uv.T

        m = np.minimum(np.floor((uv[:, 0] - (-np.pi)) / (2 * np.pi) * width),
                       width - 1)
        n = np.minimum(np.floor(((np.pi / 2) - uv[:, 1]) / (np.pi) * height),
                       height - 1)
        #drawId = sub2ind([height, width], n, m);

        panoEdgeC[np.int32(n), np.int32(m)] = 255

    return panoEdgeC
def rotatePanorama(img, vp, R):
    #ROTATEPANORAMA Rotate panorama
    #   if R is given, vp (vanishing point) will be overlooked
    #   otherwise R is computed from vp

    [sphereH, sphereW, C] = img.shape
    # rotImg = zeros( sphereH, sphereW, C);

    ## new uv coordinates
    [TX, TY] = np.meshgrid(np.arange(sphereW), np.arange(sphereH))
    TX = TX.T.flatten() + 1
    TY = TY.T.flatten() + 1
    ANGx = (TX - sphereW / 2 - 0.5) / sphereW * np.pi * 2
    ANGy = -(TY - sphereH / 2 - 0.5) / sphereH * np.pi
    uvNew = np.column_stack((ANGx, ANGy))
    xyzNew = CoordsTransform.uv2xyzN(uvNew, 0)

    ## rotation matrix
    if R == None:
        R = np.dot(np.diag([1, 1, 1]), np.linalg.pinv(vp.T))

    xyzOld = np.dot(np.linalg.pinv(R), xyzNew.T).T
    uvOld = CoordsTransform.xyz2uvN(xyzOld, 0).T

    # Px = uvOld(:,1)/2/pi*sphereW + 0.5 + sphereW/2;
    # Py = -uvOld(:,2)/pi*sphereH + 0.5 + sphereH/2;
    Px = (uvOld[:, 0] + np.pi) / (2 * np.pi) * sphereW + 0.5
    Py = (-uvOld[:, 1] + np.pi / 2) / np.pi * sphereH + 0.5

    Px = np.reshape(Px, [sphereW, sphereH]).T
    Py = np.reshape(Py, [sphereW, sphereH]).T

    # boundary
    imgNew = np.double(np.zeros([sphereH + 2, sphereW + 2, C]))
    imgNew[1:-1, 1:-1, :] = img
    imgNew[1:-1, 0, :] = img[:, -1, :]
    imgNew[1:-1, -1, :] = img[:, 0, :]

    halfW = np.int(sphereW / 2)

    imgNew[0, 1:halfW + 1, :] = img[0, sphereW:halfW - 1:-1, :]
    imgNew[0, halfW + 1:-1, :] = img[0, halfW - 1::-1, :]
    imgNew[-1, 1:halfW + 1, :] = img[-1, sphereW:halfW - 1:-1, :]
    imgNew[-1, halfW + 1:-1, :] = img[0, halfW:0:-1, :]
    imgNew[0, 0, :] = img[0, 0, :]
    imgNew[-1, -1, :] = img[-1, -1, :]
    imgNew[0, -1, :] = img[0, -1, :]
    imgNew[-1, 0, :] = img[-1, 0, :]

    rotImg = Projection.warpImageFast(imgNew, Px + 1, Py + 1)
    # rotImg = warpImageFast(img, Px, Py);

    return rotImg, R
Example #3
0
def assignVanishingType(lines, vp, tol, area):
    #ASSIGNVANISHINGTYPE Summary of this function goes here
    #   Detailed explanation goes here
    if area < 0:
        area = 10

    numLine = lines.shape[0]
    numVP = vp.shape[0]
    typeCost = np.zeros([numLine, numVP])
    # perpendicular
    for vid in np.arange(numVP):
        cosint = np.sum(lines[:, 0:3] * repmat(vp[vid, :], numLine, 1), 1)
        typeCost[:, vid] = np.arcsin(np.abs(cosint))

    # infinity
    for vid in np.arange(numVP):
        valid = np.ones([numLine, 1], dtype=bool)

        for i in np.arange(numLine):
            us = lines[i, 4]
            ue = lines[i, 5]
            u = np.array([us, ue]) * 2.0 * np.pi - np.pi
            v = CoordsTransform.computeUVN(lines[i, 0:3], u, lines[i, 3])
            xyz = CoordsTransform.uv2xyzN(np.row_stack((u, v)).T, lines[i, 3])
            x = np.linspace(xyz[0, 0], xyz[1, 0], 100)
            y = np.linspace(xyz[0, 1], xyz[1, 1], 100)
            z = np.linspace(xyz[0, 2], xyz[1, 2], 100)
            xyz = np.column_stack((x, y, z))
            xyz = xyz / repmat(np.sqrt(np.sum(xyz**2, 1)), 3, 1).T
            ang = np.arccos(np.abs(np.sum(xyz * repmat(vp[vid, :], 100, 1),
                                          1)))
            valid[i] = not any(ang < area * np.pi / 180)

        typeCost[~valid[:, 0], vid] = 100

    I = np.min(typeCost, 1)
    type = np.argmin(typeCost, 1)
    type[I > tol] = numVP

    return [type, typeCost]
def rotateLines(lines, R):
    #ROTATELINES Rotate lines on panorama
    #   lines: parameterized lines, R: rotation matrix

    [numLine, dimLine] = lines.shape
    lines_N = np.zeros([numLine, dimLine])
    for i in np.arange(numLine):
        n = lines[i, 0:3]
        sid = lines[i, 4] * 2 * np.pi - np.pi
        eid = lines[i, 5] * 2 * np.pi - np.pi
        u = np.row_stack((sid, eid))
        v = CoordsTransform.computeUVN(n, u, lines[i, 3])
        xyz = CoordsTransform.uv2xyzN(np.column_stack((u, v)), lines[i, 3])

        n_N = np.dot(R, n.T).T
        n_N = n_N / np.linalg.norm(n_N, 2)
        xyz_N = np.dot(R, xyz.T).T
        lines_N[i, 3] = np.argmax(np.abs(n_N[[2, 0, 1]]))
        uv_N = CoordsTransform.xyz2uvN(xyz_N, lines_N[i, 3]).T
        umax = max(uv_N[:, 0]) + np.pi
        umin = min(uv_N[:, 0]) + np.pi
        if umax - umin > np.pi:
            lines_N[i, 4:6] = np.array([umax, umin]) / 2 / np.pi
        else:
            lines_N[i, 4:6] = np.array([umin, umax]) / 2 / np.pi

        lines_N[i, 0:3] = n_N
        #     lines_N(i,5:6) = (uv_N(:,1)'+pi)/2/pi;
        if dimLine >= 7:
            lines_N[i, 6] = np.arccos(
                np.sum(xyz_N[0, :] * xyz_N[1, :]) /
                (np.linalg.norm(xyz_N[0, :], 2) *
                 np.linalg.norm(xyz_N[1, :], 2)))
            # lines_N(i,7) = lines(i,7); # this should be ok as well

        if dimLine >= 8:
            lines_N[i, 7] = lines[i, 7]

    return lines_N
Example #5
0
def refitLineSegmentB(lines, vp, vpweight):
    #REFITLINESEGMENTA refit direction of line segments
    #   lines: original line segments
    #   vp: vannishing point
    #   vpweight: if set to 0, lines will not change; if set to inf, lines will
    #   be forced to pass vp
    if vpweight == None:
        vpweight = 0.1

    numSample = 100
    numLine = lines.shape[0]
    xyz = np.zeros([numSample + 1, 3])
    wei = np.ones([numSample + 1, 1])
    wei[numSample] = vpweight * numSample
    lines_ali = lines
    for i in np.arange(numLine):
        n = lines[i, 0:3]
        sid = lines[i, 4] * 2 * np.pi
        eid = lines[i, 5] * 2 * np.pi
        if eid < sid:
            x = np.linspace(sid, eid + 2 * np.pi, numSample)
            x = (x % (2 * np.pi))
    #         x = sid-1:(eid-1+numBins);
    #         x = rem(x,numBins) + 1;
        else:
            x = np.linspace(sid, eid, numSample)

    #     u = -pi + (x'-1)*uBinSize + uBinSize/2;
        u = -np.pi + x.T
        v = CoordsTransform.computeUVN(n, u, lines[i, 3])
        xyz[0:numSample, :] = CoordsTransform.uv2xyzN(np.column_stack((u, v)),
                                                      lines[i, 3])
        xyz[numSample, :] = vp
        _, outputNM = curveFitting(xyz, wei)
        lines_ali[i, 0:3] = outputNM

    return lines_ali
Example #6
0
def gbPanoSegment(img, sigma, k, minSz):
    #GBPANOSEGMENT Graph-based image segmentation on panorama
    #   Similar as Pedro's algorithm, only the graph is built on sphere, so
    #   left and right side are considered as attached.
    #   img: should be in uint8 [0~256]
    #   sigma, k, minSz: same parameters as in Pedro's algorithm

    [height, width, _] = img.shape
    #img_smooth = smooth(img, sigma);

    #sigma = 10;
    img_smooth = np.zeros([height, width, 3])
    img_smooth[:, :, 0] = gaussian_filter(img[:, :, 0], sigma)
    img_smooth[:, :, 1] = gaussian_filter(img[:, :, 1], sigma)
    img_smooth[:, :, 2] = gaussian_filter(img[:, :, 2], sigma)

    #SrcImage = './data/rotImg_smooth.mat'
    #dict = loadmat(SrcImage)
    #img_smooth = dict['img_smooth']
    #plt.subplot(2, 1, 1)
    #plt.imshow(np.uint8(img))

    #plt.subplot(2, 1, 2)
    #plt.imshow(np.uint8(img_smooth))
    #plt.show()

    ## uniformly sample vectors on sphere and segment, test later
    dict = loadmat('./data/uniformvector_lvl8.mat')
    coor = dict['coor']
    tri = dict['tri']
    #[coor, tri] = getUniformVector(8);

    # [ E ] = getSketchTokenEdgemap( img );
    # [EE, Ix, Iy] = dt2(double(E), 0.1, 0, 0.1, 0 );
    EE = np.zeros([height, width])

    xySubs = CoordsTransform.uv2coords(CoordsTransform.xyz2uvN(coor, 0), width,
                                       height, 0)
    xySubs = np.int32(xySubs)

    #SrcImage = './data/xySubs.mat'
    #dict = loadmat(SrcImage)
    #xySubs = dict['xySubs']
    #xySubs = xySubs -1;

    idx = np.where(xySubs[:, 1] < 0)
    xySubs[idx, 1] = 0

    idx = np.where(xySubs[:, 1] >= 512)
    xySubs[idx, 1] = 511

    idx = np.where(xySubs[:, 0] >= 1024)
    xySubs[idx, 0] = 1023

    SubXY = np.array([xySubs[:, 1], xySubs[:, 0]]).T

    #xyinds = np.ravel_multi_index(SubXY,(height ,width));
    #offset = width*height;

    tri = tri - 1
    e0 = np.array([tri[:, 0], tri[:, 1]]).T
    e1 = np.array([tri[:, 1], tri[:, 2]]).T
    e2 = np.array([tri[:, 2], tri[:, 0]]).T

    edges = np.row_stack((e0, e1, e2))
    invert = edges[:, 1] < edges[:, 0]
    edges[invert, :] = edges[invert, 1::-1]

    uniEdges, _ = np.unique(edges, return_inverse=True, axis=0)

    #eid0 = np.unravel_index(xyinds[uniEdges[:,0]],(height,width,3))
    #eid1 = np.unravel_index(xyinds[uniEdges[:,1]],(height,width,3))

    eid0 = SubXY[uniEdges[:, 0], :].T
    eid1 = SubXY[uniEdges[:, 1], :].T

    #eid0offset =  np.unravel_index(xyinds[uniEdges[:,0]] + offset,(height,width,3))
    #eid1offset =  np.unravel_index(xyinds[uniEdges[:,1]] + offset,(height,width,3))

    #eid0offset2 =  np.unravel_index(xyinds[uniEdges[:,0]] + 2 * offset,(height,width,3))
    #eid1offset2 =  np.unravel_index(xyinds[uniEdges[:,1]] + 2 * offset,(height,width,3))

    if any(eid0[:, 0] >= 512):
        print('nono')

    weight = (img_smooth[eid0[0], eid0[1], 0] - img_smooth[eid1[0], eid1[1], 0]
              )**2 + (img_smooth[eid0[0], eid0[1], 1] -
                      img_smooth[eid1[0], eid1[1], 1])**2 + (
                          img_smooth[eid0[0], eid0[1], 2] -
                          img_smooth[eid1[0], eid1[1], 2])**2
    gdweight = (EE[eid0[0], eid0[1]] + EE[eid0[0], eid0[1]]) / 2
    panoEdge = np.array([
        uniEdges[:, 0], uniEdges[:, 1],
        np.sqrt(np.double(weight)) + 10 * np.double(gdweight)
    ])

    maxID = coor.shape[0]
    num = uniEdges.shape[0]

    edgeLabel = segmentGraphEdge((maxID, num, panoEdge, k, minSz))

    L = np.unique(edgeLabel)
    temp = np.zeros(len(edgeLabel))

    [gridX, gridY] = np.meshgrid(np.arange(width), np.arange(height))

    for i in np.arange(len(L)):
        temp[edgeLabel == L[i]] = i + 1

    pixelvector = CoordsTransform.uv2xyzN(
        CoordsTransform.coords2uv([gridX[:] + 1, gridY[:] + 1], width, height),
        0)

    # k = 1;
    # [nnidx, dists] = annsearch( coor', pixelvector', k);
    #[nnidx, dists] = knnsearch( coor, pixelvector);

    nbrs = NearestNeighbors(n_neighbors=1, algorithm='auto').fit(coor)
    dists, nnidx = nbrs.kneighbors(pixelvector)

    #from scipy import spatial
    #tree = spatial.KDTree(coor);
    #dists, nnidx  = tree.query(pixelvector,k=1);

    #SrcImage = './data/temp.mat'
    #dict = loadmat(SrcImage)
    #tempm = dict['temp']

    #SrcImage = './data/nnidx.mat'
    #dict = loadmat(SrcImage)
    #nnidxm = dict['nnidx']
    #nnidxm = nnidxm - 1
    panoSegment = np.reshape(temp[nnidx], [width, height]).T

    #pimg = PIL.Image.fromarray(np.uint8(panoSegment))
    ##pimggray = pimg.convert('L')

    #pimg.save('./data/segmentation.jpg');

    return panoSegment
Example #7
0
def combineEdgesN(edges):
    #COMBINEEDGES Combine some small line segments, should be very conservative
    #   lines: combined line segments
    #   ori_lines: original line segments
    #   line format: [nx ny nz projectPlaneID umin umax LSfov score]
    arcList = []
    for i in np.arange(edges.shape[0]):
        panoLst = edges[i].panoLst
        if panoLst[0].shape[0] == 0:
            continue

        if (len(arcList)) == 0:
            arcList = panoLst
        else:
            arcList = np.row_stack((arcList, panoLst))

    ## ori lines
    numLine = arcList.shape[0]
    ori_lines = np.zeros((numLine, 8))
    areaXY = np.abs(
        np.sum(arcList[:, 0:3] * repmat([0, 0, 1], arcList.shape[0], 1), 1))
    areaYZ = np.abs(
        np.sum(arcList[:, 0:3] * repmat([1, 0, 0], arcList.shape[0], 1), 1))
    areaZX = np.abs(
        np.sum(arcList[:, 0:3] * repmat([0, 1, 0], arcList.shape[0], 1), 1))

    vec = [areaXY, areaYZ, areaZX]

    #[_, planeIDs] = np.max(vec,  1); # 1:XY 2:YZ 3:ZX
    planeIDs = np.argmax(vec, 0)

    for i in np.arange(numLine):
        ori_lines[i, 0:3] = arcList[i, 0:3]
        ori_lines[i, 3] = planeIDs[i]
        coord1 = arcList[i, 3:6]
        coord2 = arcList[i, 6:9]

        uv = CoordsTransform.xyz2uvN(np.row_stack((coord1, coord2)),
                                     planeIDs[i])
        umax = np.max(uv[0, :]) + np.pi
        umin = np.min(uv[0, :]) + np.pi
        if umax - umin > np.pi:
            ori_lines[i, 4:6] = np.column_stack((umax, umin)) / 2 / np.pi
    #         ori_lines(i,7) = umin + 1 - umax;
        else:
            ori_lines[i, 4:6] = np.column_stack((umin, umax)) / 2 / np.pi
    #         ori_lines(i,7) = umax - umin;

        ori_lines[i, 6] = np.arccos(
            np.sum(coord1 * coord2) /
            (np.linalg.norm(coord1, 2) * np.linalg.norm(coord2, 2)))
        ori_lines[i, 7] = arcList[i, 9]

    # valid = ori_lines(:,3)<0;
    # ori_lines(valid,1:3) = -ori_lines(valid,1:3);

    ## additive combination
    lines = ori_lines
    # panoEdge = paintParameterLine( lines, 1024, 512);
    # figure; imshow(panoEdge);
    for iter in np.arange(3):
        numLine = lines.shape[0]
        valid_line = np.ones([numLine], dtype=bool)
        for i in np.arange(numLine):
            #         fprintf('#d/#d\n', i, numLine);
            if valid_line[i] == False:
                continue

            dotProd = np.sum(lines[:, 0:3] * repmat(lines[i, 0:3], numLine, 1),
                             1)
            valid_curr = (np.abs(dotProd) > np.cos(
                1 * np.pi / 180)) & valid_line
            valid_curr[i] = False
            valid_ang = np.where(valid_curr)
            for j in valid_ang[0]:
                range1 = lines[i, 4:6]
                range2 = lines[j, 4:6]
                valid_rag = intersection(range1, range2)
                if valid_rag == False:
                    continue

                # combine
                I = np.argmax(np.abs(lines[i, 0:3]))
                if lines[i, I] * lines[j, I] > 0:
                    nc = lines[i, 0:3] * lines[i, 6] + lines[j, 0:3] * lines[j,
                                                                             6]
                else:
                    nc = lines[i, 0:3] * lines[i, 6] - lines[j, 0:3] * lines[j,
                                                                             6]

                nc = nc / np.linalg.norm(nc, 2)

                if insideRange(range1[0], range2):
                    nrmin = range2[0]
                else:
                    nrmin = range1[0]

                if insideRange(range1[1], range2):
                    nrmax = range2[1]
                else:
                    nrmax = range1[1]

                u = np.array([nrmin, nrmax]) * 2 * np.pi - np.pi
                v = CoordsTransform.computeUVN(nc, u, lines[i, 3])
                xyz = CoordsTransform.uv2xyzN(np.column_stack((u, v)),
                                              lines[i, 3])
                length = np.arccos(np.sum(xyz[0, :] * xyz[1, :]))
                scr = (lines[i, 6] * lines[i, 7] +
                       lines[j, 6] * lines[j, 7]) / (lines[i, 6] + lines[j, 6])

                nc = np.append(nc, lines[i, 3])
                nc = np.append(nc, nrmin)
                nc = np.append(nc, nrmax)
                nc = np.append(nc, length)
                nc = np.append(nc, scr)
                newLine = nc
                lines[i, :] = newLine
                valid_line[j] = False

        lines = lines[valid_line, :]
        print('iter: #d, before: #d, after: #d\n', iter, len(valid_line),
              sum(valid_line))

    return [lines, ori_lines]
    '''