def paintParameterLine(parameterLine, width, height): lines = parameterLine.copy() panoEdgeC = np.zeros((height, width)) num_sample = max(height, width) for i in range(len(lines)): n = lines[i, :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) else: x = np.linspace(sid, eid, num_sample) u = -np.pi + x.reshape(-1, 1) v = computeUVN(n, u, lines[i, 3]) xyz = uv2xyzN(np.hstack([u, v]), lines[i, 3]) uv = xyz2uvN(xyz, 1) m = np.minimum( np.floor((uv[:, 0] + np.pi) / (2 * np.pi) * width) + 1, width).astype(np.int32) n = np.minimum( np.floor(((np.pi / 2) - uv[:, 1]) / np.pi * height) + 1, height).astype(np.int32) panoEdgeC[n - 1, m - 1] = i return panoEdgeC
def refitLineSegmentB(lines, vp, vpweight=0.1): ''' Refit direction of line segments INPUT: 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 ''' numSample = 100 numLine = len(lines) xyz = np.zeros((numSample + 1, 3)) wei = np.ones((numSample + 1, 1)) wei[numSample] = vpweight * numSample lines_ali = lines.copy() for i in range(numLine): n = lines[i, :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) % (2 * np.pi) else: x = np.linspace(sid, eid, numSample) u = -np.pi + x.reshape(-1, 1) v = computeUVN(n, u, lines[i, 3]) xyz[:numSample] = uv2xyzN(np.hstack([u, v]), lines[i, 3]) xyz[numSample] = vp outputNM = curveFitting(xyz, wei) lines_ali[i, :3] = outputNM return lines_ali
def rotatePanorama(img, vp=None, R=None): ''' Rotate panorama if R is given, vp (vanishing point) will be overlooked otherwise R is computed from vp ''' sphereH, sphereW, C = img.shape # new uv coordinates TX, TY = np.meshgrid(range(1, sphereW + 1), range(1, sphereH + 1)) TX = TX.reshape(-1, 1, order='F') TY = TY.reshape(-1, 1, order='F') ANGx = (TX - sphereW / 2 - 0.5) / sphereW * np.pi * 2 ANGy = -(TY - sphereH / 2 - 0.5) / sphereH * np.pi uvNew = np.hstack([ANGx, ANGy]) xyzNew = uv2xyzN(uvNew, 1) # rotation matrix if R is None: R = np.linalg.inv(vp.T) xyzOld = np.linalg.solve(R, xyzNew.T).T uvOld = xyz2uvN(xyzOld, 1) Px = (uvOld[:, 0] + np.pi) / (2 * np.pi) * sphereW + 0.5 Py = (-uvOld[:, 1] + np.pi / 2) / np.pi * sphereH + 0.5 Px = Px.reshape(sphereH, sphereW, order='F') Py = Py.reshape(sphereH, sphereW, order='F') # boundary imgNew = np.zeros((sphereH + 2, sphereW + 2, C), np.float64) imgNew[1:-1, 1:-1, :] = img imgNew[1:-1, 0, :] = img[:, -1, :] imgNew[1:-1, -1, :] = img[:, 0, :] imgNew[0, 1:sphereW // 2 + 1, :] = img[0, sphereW - 1:sphereW // 2 - 1:-1, :] imgNew[0, sphereW // 2 + 1:-1, :] = img[0, sphereW // 2 - 1::-1, :] imgNew[-1, 1:sphereW // 2 + 1, :] = img[-1, sphereW - 1:sphereW // 2 - 1:-1, :] imgNew[-1, sphereW // 2 + 1:-1, :] = img[0, sphereW // 2 - 1::-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 = warpImageFast(imgNew, Px + 1, Py + 1) return rotImg
def combineEdgesN(edges): ''' Combine some small line segments, should be very conservative OUTPUT lines: combined line segments ori_lines: original line segments line format [nx ny nz projectPlaneID umin umax LSfov score] ''' arcList = [] for edge in edges: panoLst = edge['panoLst'] if len(panoLst) == 0: continue arcList.append(panoLst) arcList = np.vstack(arcList) # ori lines numLine = len(arcList) ori_lines = np.zeros((numLine, 8)) areaXY = np.abs(arcList[:, 2]) areaYZ = np.abs(arcList[:, 0]) areaZX = np.abs(arcList[:, 1]) planeIDs = np.argmax(np.stack([areaXY, areaYZ, areaZX], -1), 1) + 1 # XY YZ ZX for i in range(numLine): ori_lines[i, :3] = arcList[i, :3] ori_lines[i, 3] = planeIDs[i] coord1 = arcList[i, 3:6] coord2 = arcList[i, 6:9] uv = xyz2uvN(np.stack([coord1, coord2]), planeIDs[i]) umax = uv[:, 0].max() + np.pi umin = uv[:, 0].min() + np.pi if umax - umin > np.pi: ori_lines[i, 4:6] = np.array([umax, umin]) / 2 / np.pi else: ori_lines[i, 4:6] = np.array([umin, umax]) / 2 / np.pi ori_lines[i, 6] = np.arccos( (np.dot(coord1, coord2) / (np.linalg.norm(coord1) * np.linalg.norm(coord2))).clip(-1, 1)) ori_lines[i, 7] = arcList[i, 9] # additive combination lines = ori_lines.copy() for _ in range(3): numLine = len(lines) valid_line = np.ones(numLine, bool) for i in range(numLine): if not valid_line[i]: continue dotProd = (lines[:, :3] * lines[[i], :3]).sum(1) valid_curr = np.logical_and( (np.abs(dotProd) > np.cos(np.pi / 180)), valid_line) valid_curr[i] = False for j in np.nonzero(valid_curr)[0]: range1 = lines[i, 4:6] range2 = lines[j, 4:6] valid_rag = _intersection(range1, range2) if not valid_rag: continue # combine I = np.argmax(np.abs(lines[i, :3])) if lines[i, I] * lines[j, I] > 0: nc = lines[i, :3] * lines[i, 6] + lines[j, :3] * lines[j, 6] else: nc = lines[i, :3] * lines[i, 6] - lines[j, :3] * lines[j, 6] nc = nc / np.linalg.norm(nc) 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 = computeUVN(nc, u, lines[i, 3]) xyz = uv2xyzN(np.hstack([u, v]), lines[i, 3]) l = np.arccos(np.dot(xyz[0, :], xyz[1, :]).clip(-1, 1)) scr = (lines[i, 6] * lines[i, 7] + lines[j, 6] * lines[j, 7]) / (lines[i, 6] + lines[j, 6]) lines[i] = [*nc, lines[i, 3], nrmin, nrmax, l, scr] valid_line[j] = False lines = lines[valid_line] return lines, ori_lines