首页 > 解决方案 > 如何在python中的自制旋转算法中正确拟合图像

问题描述

我根据如何旋转图像自己制作了这个算法。

import cv2
import math
import numpy as np

class rotation:
    angle = 60.0
    x = 100
    y = 100
    img = cv2.imread('FNAF.png',0)
    width,height = img.shape
    def showImage(name, self):
        cv2.imshow(name, self.img)
    def printWidthHeight(self):
        print(self.width)
        print(self.height)
    def rotateImage(self):
        ForwardMap = np.zeros((self.width,self.height),dtype="uint8")
        BackwardMap = np.zeros((self.width,self.height),dtype="uint8")

        for i in range(self.width):
            for j in range(self.height):
                # forward mapping
                for_x = (i - self.x) * math.cos(self.angle*(math.pi/180)) - (j - self.y) * math.sin(self.angle*(math.pi/180)) + self.x
                for_y = (i - self.x) * math.sin(self.angle*(math.pi/180)) + (j - self.y) * math.cos(self.angle*(math.pi/180)) + self.x
                for_x = int(for_x)
                for_y = int(for_y)
                # backward mapping should change the forward mapping to the original image
                back_x = (i - self.x) * math.cos(self.angle*(math.pi/180)) + (j - self.y) * math.sin(self.angle*(math.pi/180)) + self.x
                back_y = -(i - self.x) * math.sin(self.angle*(math.pi/180)) + (j - self.y) * math.cos(self.angle*(math.pi/180)) + self.x
                back_x = int(back_x)
                back_y = int(back_y)
                if for_x in range(self.width) and for_y in range(self.height):
                    ForwardMap[i, j] = self.img[for_x, for_y]
                else:
                    pass
                if back_x in range(self.width) and back_y in range(self.height):
                    BackwardMap[i, j] = self.img[back_x, back_y]
                else:
                    pass
        cv2.imshow('Forward Mapping', ForwardMap)
        cv2.imshow('Backward Mapping', BackwardMap)
def demo():
    rotation.showImage('normal', rotation)
    rotation.printWidthHeight(rotation)
    rotation.rotateImage(rotation)
    cv2.waitKey(0)
    cv2.destroyAllWindows

if __name__ == '__main__':
    demo()

我现在的问题是我想让旋转的图片(用于正向和反向映射)正好适合,所以没有不必要的空间使用。有人可以帮我吗?非常感激。

如果您对优化我的代码有任何建议,也请随时发表评论。

标签: pythonimageopencvmathimage-processing

解决方案


您的原始图像有 4 个角,坐标:(0,0)、(w-1, 0)、(0,h-1) 和 (w-1, h-1)。既然你的变换是仿射的,为什么不把这些坐标变换成目标坐标呢?

  • (0,0) → (x1, y1)
  • (w-1, 0) → (x2, y2)
  • (0, h-1) → (x3, y3)
  • (w-1, h-1) → (x4, y4)

您的目标图像大小为:

width  = max(x1, x2, x3, x4) - min(x1, x2, x3, x4)
height = max(y1, y2, y3, y4) - min(y1, y2, y3, y4)

推荐阅读