import cv2 import numpy as np img = cv2.imread('image/turtle.jpg') size = img.shape[:-1] cv2.namedWindow('img') #缩放矩阵 def GetResizeMatrix(scalex,scaley): M = np.zeros((3,3),dtype=np.float32) M.itemset((0,0),scalex) M.itemset((1,1),scaley) M.itemset((2,2),1) return M #平移矩阵 def GetMoveMatrix(x,y): M = np.zeros((3, 3), dtype=np.float32) M.itemset((0, 0), 1) M.itemset((1, 1), 1) M.itemset((2, 2), 1) M.itemset((0, 2), x) M.itemset((1, 2), y) return M #旋转矩阵 def GetRotationMatrix(angle): M = np.zeros((3, 3), dtype=np.float32) M.itemset((0, 0), np.cos(angle)) M.itemset((0, 1), -np.sin(angle)) M.itemset((1, 0), np.sin(angle)) M.itemset((1, 1), np.cos(angle)) M.itemset((2, 2), 1) return M def InterLinearMap(img,mapx,mapy): #(rows,cols) inty = np.int32(mapy) intx = np.int32(mapx) nxty = 1+inty nxtx = 1+intx #(rows,cols) party = mapy - inty partx = mapx - intx resy = 1-party resx = 1-partx #(4,rows,cols) mxy = np.stack((resy*partx,resy*resx,partx*party, resx*party)) mxy = np.expand_dims(mxy,axis=-1) #(4,rows,cols,3) mf = np.stack((img[inty,nxtx],img[inty,intx],img[nxty,nxtx],img[nxty,intx])) #res -> shape(rows,cols,3) res = np.sum(mxy*mf,axis=0) res = np.uint8(res+0.5) return res def WarpAffine(img,Mat,size): rows = size[0] cols = size[1] #生成矩阵[X Y 1] ones = np.ones((rows, cols), dtype=np.float32) #gridx/gridy -> shape(rows,cols) gridx,gridy= np.meshgrid(np.arange(0, cols),np.arange(0, rows)) #dst -> shape(3,rows,cols) dst = np.stack((gridx, gridy, ones)) #求逆矩阵 M -> shape(3,3) Mat = np.linalg.inv(Mat) #获得矩阵[x,y,1] -> shape(3,rows,cols) src = np.tensordot(Mat,dst,axes=[[-1],[0]]) #mapx/mapy -> shape(rows,cols) mapx = src[0]#坐标非整数 mapy = src[1]#坐标非整数 #仿射出界的设为原点 flags = (mapy > rows - 2) + (mapy < 0) + (mapx > cols - 2) + (mapx < 0) mapy[flags] = 0 mapx[flags] = 0 #双线性插值 result = InterLinearMap(img, mapx, mapy) return result if __name__ == '__main__': center_x = size[1]/2 center_y = size[0]/2 for x in np.linspace(0,2*np.pi,100): angle = 360*x/2/np.pi scale = 0.2+0.2*np.sin(x) path_x = x*50+100 path_y = (np.sin(x)+1)*100+100 M = GetMoveMatrix(path_x,path_y)@GetRotationMatrix(x)\ @GetResizeMatrix(scale,scale)@GetMoveMatrix(-center_x,-center_y) dst = WarpAffine(img,M,size) cv2.imshow('img',dst) cv2.waitKey(1)