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 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
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
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] '''