OpenCV python3 не может правильно повернуть изображение назад

Я хочу использовать python3 с пакетами OpenCV, чтобы повернуть изображение на 15 градусов и повернуть его обратно. Однако приведенный ниже код не работает, но я думаю, что в кодах нет логической ошибки. В окне «БЛИЖАЙШЕЕ» изображение поворачивается правильно, но в окне «БЛИЖАЙШЕЕ-ОК-ВОССТАНОВЛЕНИЕ» изображение не поворачивается обратно в исходное положение (показывается в «исходном» окне).

введите здесь описание изображения

#! /usr/bin/env python3
#! -*- coding:utf-8 -*-

import cv2
import numpy as np

imgmat = cv2.imread('./lena.jpg',255)
print(hex(id(imgmat)))

cv2.imshow('original',imgmat)

rows,cols = imgmat.shape

M = cv2.getRotationMatrix2D((cols/2,rows/2),-15,1)
dst = cv2.warpAffine(src=imgmat,M=M,dsize=(cols,rows),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)))
cv2.imshow('NEAREST-OK-RESTORE',dst)

cv2.waitKey(0)

Тестовое изображение находится здесь: введите здесь описание изображения


person zqer    schedule 27.03.2018    source источник
comment
кажется, не работает -- в каком смысле? Что вы ожидаете получить и чем результат отличается от этого ожидания? Для меня результат выглядит так, как и ожидалось - ориентация Лены такая же, как и в оригинале, а углы, выходящие за пределы области изображения на промежуточном изображении, черные, так как эта информация была потеряна.   -  person Dan Mašek    schedule 27.03.2018
comment
Это не похоже на операцию отмены. Повернутые пиксели забываются, входящие черные пиксели становятся частью изображения. Если вы повернете назад, они останутся, а дополнительные новые черные пиксели будут повернуты.   -  person guidot    schedule 27.03.2018
comment
@DanMašek Хорошо, спасибо. Обрезанные изображения слепят глаза!   -  person zqer    schedule 27.03.2018
comment
@guidot Спасибо. Я знаю, в чем проблема.   -  person zqer    schedule 27.03.2018
comment
@Angusme Я написал ответ, который решает вашу проблему. Он использует описанную выше концепцию, чтобы помочь вам восстановить исходное изображение. Дайте мне знать, если вам нужна дополнительная помощь.   -  person rayryeng    schedule 28.03.2018
comment
@rayryeng Спасибо за вашу любезную помощь, и ответ принят.   -  person zqer    schedule 29.03.2018
comment
@Angusme Добро пожаловать! Удачи.   -  person rayryeng    schedule 29.03.2018


Ответы (1)


Причина, по которой это происходит, заключается в том, что когда вы выполняете вращение, это происходит в пределах диапазона размеров исходного изображения, поэтому это приводит к обрезке изображения, если вы поворачиваете изображение, и полученные угловые точки выходят за пределы исходного изображения. Габаритные размеры.

Что вам нужно сделать, так это обнулить изображение, чтобы повернутое изображение полностью содержалось внутри него, поверните это изображение, а затем, когда вы повернете его назад, вам придется обрезать результат.

Чтобы выяснить, насколько обнулить ваше изображение, обратите внимание, что максимально возможные размеры вашего изображения будут, когда изображение повернуто на 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()

Теперь я получаю:

введите здесь описание изображения

person rayryeng    schedule 27.03.2018