How can I use scipy.ndimage.interpolation.affine_transform to rotate an image about its centre?

后端 未结 3 871
刺人心
刺人心 2020-12-23 22:52

I am perplexed by the API to scipy.ndimage.interpolation.affine_transform. And judging by this issue I\'m not the only one. I\'m actually wanting to do more interesting th

3条回答
  •  萌比男神i
    2020-12-23 23:18

    Once treddy's answer got me a working baseline, I managed to get a better working model of affine_transform. It's not actually as odd as the issue linked in the original question hints.

    Basically, each point (coordinate) p in the output image is transformed to pT+s where T and s are the matrix and offset passed to the function. So if we want point c_out in the output to be mapped to and sampled from c_in from the input image, with rotation R and (possibly anisotropic) scaling S we need pT+s = (p-c_out)RS+c_in which can be rearranged to yield s = (c_int-c_out)T (with T=RS).

    For some reason I then need to pass transform.T to affine_transform but I'm not going to worry about that too much; probably something to do with row-coordinates with transforms on the right (assumed above) vs column-coordinates with transforms on the left.

    So here's a simple test rotating a centred image:

    src=scipy.misc.lena()
    c_in=0.5*array(src.shape)
    c_out=array((256.0,256.0))
    for i in xrange(0,7):
        a=i*15.0*pi/180.0
        transform=array([[cos(a),-sin(a)],[sin(a),cos(a)]])
        offset=c_in-c_out.dot(transform)
        dst=scipy.ndimage.interpolation.affine_transform(
            src,transform.T,order=2,offset=offset,output_shape=(512,512),cval=0.0,output=float32
        )
        subplot(1,7,i+1);axis('off');imshow(dst,cmap=cm.gray)
    show()
    

    Spinning Lena

    Here's it modified for different image sizes

    src=scipy.misc.lena()[::2,::2]
    c_in=0.5*array(src.shape)
    c_out=array((256.0,256.0))
    for i in xrange(0,7):
        a=i*15.0*pi/180.0
        transform=array([[cos(a),-sin(a)],[sin(a),cos(a)]])
        offset=c_in-c_out.dot(transform)
        dst=scipy.ndimage.interpolation.affine_transform(
            src,transform.T,order=2,offset=offset,output_shape=(512,512),cval=0.0,output=float32
        )
        subplot(1,7,i+1);axis('off');imshow(dst,cmap=cm.gray)
    show()
    

    Spinning small Lena

    And here's a version with anisotropic scaling to compensate for the anisotropic resolution of the source image.

    src=scipy.misc.lena()[::2,::4]
    c_in=0.5*array(src.shape)
    c_out=array((256.0,256.0))
    for i in xrange(0,7):
        a=i*15.0*pi/180.0
        transform=array([[cos(a),-sin(a)],[sin(a),cos(a)]]).dot(diag(([0.5,0.25])))
        offset=c_in-c_out.dot(transform)
        dst=scipy.ndimage.interpolation.affine_transform(
            src,transform.T,order=2,offset=offset,output_shape=(512,512),cval=0.0,output=float32
        )
        subplot(1,7,i+1);axis('off');imshow(dst,cmap=cm.gray)
    show() 
    

    Spinning anisotropic Lena

提交回复
热议问题