image information along a polar coordinate system

后端 未结 2 1008
予麋鹿
予麋鹿 2020-12-05 05:10

I have a set of png images that I would like to process with Python and associated tools. Each image represents a physical object with known dimensions.

In each imag

2条回答
  •  遥遥无期
    2020-12-05 05:46

    Here's my take using scipy's geometric_transform method:

    topolar.py

    import numpy as np
    from scipy.ndimage.interpolation import geometric_transform
    
    def topolar(img, order=1):
        """
        Transform img to its polar coordinate representation.
    
        order: int, default 1
            Specify the spline interpolation order. 
            High orders may be slow for large images.
        """
        # max_radius is the length of the diagonal 
        # from a corner to the mid-point of img.
        max_radius = 0.5*np.linalg.norm( img.shape )
    
        def transform(coords):
            # Put coord[1] in the interval, [-pi, pi]
            theta = 2*np.pi*coords[1] / (img.shape[1] - 1.)
    
            # Then map it to the interval [0, max_radius].
            #radius = float(img.shape[0]-coords[0]) / img.shape[0] * max_radius
            radius = max_radius * coords[0] / img.shape[0]
    
            i = 0.5*img.shape[0] - radius*np.sin(theta)
            j = radius*np.cos(theta) + 0.5*img.shape[1]
            return i,j
    
        polar = geometric_transform(img, transform, order=order)
    
        rads = max_radius * np.linspace(0,1,img.shape[0])
        angs = np.linspace(0, 2*np.pi, img.shape[1])
    
        return polar, (rads, angs)
    

    And here's some test usage:

    testpolar.py

    from topolar import topolar
    from skimage.data import chelsea
    
    import matplotlib.pyplot as plt
    
    img = chelsea()[...,0] / 255.
    pol, (rads,angs) = topolar(img)
    
    fig,ax = plt.subplots(2,1,figsize=(6,8))
    
    ax[0].imshow(img, cmap=plt.cm.gray, interpolation='bicubic')
    
    ax[1].imshow(pol, cmap=plt.cm.gray, interpolation='bicubic')
    
    ax[1].set_ylabel("Radius in pixels")
    ax[1].set_yticks(range(0, img.shape[0]+1, 50))
    ax[1].set_yticklabels(rads[::50].round().astype(int))
    
    ax[1].set_xlabel("Angle in degrees")
    ax[1].set_xticks(range(0, img.shape[1]+1, 50))
    ax[1].set_xticklabels((angs[::50]*180/3.14159).round().astype(int))
    
    plt.show()
    

    ... and the output:

提交回复
热议问题