Причина, по которой это происходит, заключается в том, что когда вы выполняете вращение, это происходит в пределах диапазона размеров исходного изображения, поэтому это приводит к обрезке изображения, если вы поворачиваете изображение, и полученные угловые точки выходят за пределы исходного изображения. Габаритные размеры.
Что вам нужно сделать, так это обнулить изображение, чтобы повернутое изображение полностью содержалось внутри него, поверните это изображение, а затем, когда вы повернете его назад, вам придется обрезать результат.
Чтобы выяснить, насколько обнулить ваше изображение, обратите внимание, что максимально возможные размеры вашего изображения будут, когда изображение повернуто на 45 градусов. Это означает, что диагональ изображения теперь будет равна количеству строк в изображении. Поэтому заполните ваше изображение нулями, чтобы мы могли, по крайней мере, сохранить изображение при повороте на 45 градусов, повернуть это изображение, и когда вы повернетесь назад, вам придется обрезать результат.
Вы можете использовать numpy.pad
, чтобы сделать это за вас и когда вы закончите, вы можете просто обрезать результат:
Для этого я внес следующие изменения в ваш код:
import cv2
import numpy as np
imgmat = cv2.imread('./lena.jpg',255)
print(hex(id(imgmat)))
cv2.imshow('original',imgmat)
rows,cols = imgmat.shape
# NEW - Determine the diagonal length of the image
diagonal = int(np.ceil(np.sqrt(rows**2.0 + cols**2.0)))
# NEW - Determine how many pixels we need to pad to the top/bottom and left/right
pp_r, pp_c = (diagonal - rows) // 2, (diagonal - cols) // 2
# NEW - Pad the image
imgmat_copy = np.pad(imgmat, ((pp_r, pp_r), (pp_c, pp_c)), 'constant', constant_values=(0,0))
### Your code as before - note we are rotating the zero padded image
rows,cols = imgmat_copy.shape
M = cv2.getRotationMatrix2D((cols/2,rows/2),-15,1)
dst = cv2.warpAffine(src=imgmat_copy,M=M,dsize=imgmat_copy.shape,flags=cv2.INTER_NEAREST)
print(hex(id(dst)))
cv2.imshow('NEAREST',dst)
OKMM = cv2.invertAffineTransform(M)
dst = cv2.warpAffine(dst,OKMM,(cols,rows),flags = cv2.INTER_NEAREST)
print(hex(id(dst)))
# NEW - Crop the image
dst = dst[pp_r:-pp_r+1,pp_c:-pp_c+1]
cv2.imshow('NEAREST-OK-RESTORE',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
Теперь я получаю:
![введите здесь описание изображения](https://i.stack.imgur.com/iDnWI.png)
person
rayryeng
schedule
27.03.2018