pythoncurve-fittingpoint-clouds3d-reconstruction

cyilnder fitting through 2d cross sections


I am trying to develop a python code that reconstructs 3D geometric primitives from point cloud. I am starting with cylinders. I should process by slicing. So now I have a set of 2D cross-sections. I have fitted circles to the extracted contours. But I don't konw how to fit a cylinder that passes through the cicles I have. Could anyone help me please. PS: I'm a beginner on Python thx enter image description here


Solution

  • I have solved the problem by fitting a line to the centers of the fitted circles. this represents the axis of my cylinder and I have the raduis that is the mean value of the raduis of cross-section cercles. Still I need to find the exact heigh of my cylinde.

    fit_data = []
    Rad = []
    ##
    
    for i in range (len(C)):
    
        data= C[i][0]
        xc,yc,r,s = cf.least_squares_circle(data)
        fit_data.append([xc,yc,data[0,2]])
        Rad.append(r)
        cf.plot_data_circle(data[:,0], data[:,1],xc,yc,r)
    fit_data=np.array(fit_data) 
    print(fit_data,"\n radius =", Rad)
    Center = np.mean(fit_data, axis=0)
    
    R = np.mean(Rad)
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.set_xlim3d(0, 120)
    ax.set_ylim3d(0,120)
    ax.set_zlim3d(0,120)
    ax.add_collection3d(Poly3DCollection(m.vectors, facecolors='y', linewidths=1, alpha=0.2))
    ax.scatter(fit_data[:,0], fit_data[:,1], fit_data[:,2], c='blue')
    ax.scatter(verts[:,0], verts[:,1], verts[:,2], c='y')
    
    
    datamean = fit_data.mean(axis=0)
    
    # Do an SVD on the mean-centered data.
    uu, dd, vv = np.linalg.svd(fit_data - datamean)
    
    # Now vv[0] contains the first principal component, i.e. the direction
    # vector of the 'best fit' line in the least squares sense.
    
    # Now generate some points along this best fit line, for plotting.
    
    
    linepts = vv[0] * np.mgrid[-60:60:2j][:, np.newaxis]
    
    # shift by the mean to get the line in the right place
    linepts += datamean
    ax.plot(linepts[:,0], linepts[:,1], linepts[:,2], 'r', label = 'fitted axis')
    
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.legend()
    
    plt.show()
    
    print ("Mean Radius=", R , "\n Center = " , Center)