#!/usr/bin/env python3
import cv2
import numpy as np
import math
def sheer(img, ratio, y=False, origin=None):
result = img.copy()
if y:
result = np.transpose(result, (1, 0, 2))
if origin is None:
origin = result.shape[0] / 2
for i in range(result.shape[0]):
shift = round((i - origin) * ratio)
if shift > 0:
result[i,shift:] = result[i,:-shift]
elif shift < 0:
result[i,:shift] = result[i,-shift:]
if y:
result = np.transpose(result, (1, 0, 2))
return result
def rotate(img, angle):
img = sheer(img, -math.tan(angle / 2))
img = sheer(img, math.sin(angle), y=True)
img = sheer(img, -math.tan(angle / 2))
return img
if __name__ == '__main__':
a = cv2.imread('fox.png')
# Photo by Jeremy Hynes https://unsplash.com/photos/UeCG6uMSKdE
b = a.copy()
for i in range(120):
b = rotate(b, math.pi / 6)
cv2.imshow('result', b)
cv2.waitKey()
Look at what I got with this code https://i.imgur.com/BhrRrJG.png
The code was slightly modified (+0.5 to origin, otherwise it looked bad)
This extremely naive implementation of mine survives 12000 rotations by 30 degrees!