一、扩展缩放


扩展缩放只是改变图像的大小。OpenCV提供函数cv.resize()实现这个功能。在缩放时推荐使用cv.INTER_AREA,在扩展时推荐使用cv.INTER_CUBIC(慢)和cv.INTER_LINEAR。


#扩展缩放
def resize_demo(img):
    #使用缩放因子
    res = cv.resize(img, None, fx=2, fy=2, interpolation=cv.INTER_CUBIC)
    cv.imshow('resize 2', res)

    height, width = img.shape[:2]
    #指定输出图像大小,输出图像的尺寸必须是整数
    res = cv.resize(img, (int(0.5 * width), int(0.5 * height)), interpolation=cv.INTER_AREA)
    cv.imshow('resize 0.5', res)




OPENCV 计算一条直线角度_缩放



二、平移


平移就是将对象换一个位置。如果要沿(x, y)方向移动,移动的距离是(tx, ty),使用numpy构建一个2x3矩阵(数据类型是float32),


                M= [[1 0 tx]


                        [0 1 ty]] ,下面的例子被移动了(100,50)个像素


#平移
def translation_demo(img):
    trans = np.array([[1, 0, 100],
                      [0, 1, 50]], dtype=np.float32)
    dstImg = cv.warpAffine(img, M=trans, dsize=(img.shape[0], img.shape[1]), borderValue=(127, 127, 127))
    cv.imshow('dstimg', dstImg)



OPENCV 计算一条直线角度_OPENCV 计算一条直线角度_02



三、旋转


对一个图像旋转角度θ,需要使用到下面形式的旋转矩阵。



OPENCV 计算一条直线角度_OpenCV_03

但是OpenCV允许在任意地方进行旋转,但是旋转矩阵应该修改为:



OPENCV 计算一条直线角度_仿射变换_04

其中:α = scale * cosθ,β = scale * sinθ


#旋转
def rotate_demo(img):
    rows, cols = img.shape[:2]
    #getRotationMatrix2D(旋转中心,旋转角度, 旋转图像缩放大小)
    M = cv.getRotationMatrix2D((rows/2, cols/2), 45, 0.6)
    dst = cv.warpAffine(img, M, (cols, rows))
    cv.imshow('rotate', dst)



OPENCV 计算一条直线角度_OPENCV 计算一条直线角度_05


函数:getRotationMatrix2D(center, angle, scale),第一个参数是旋转中心,第二个为旋转角度,第三个为旋转后的图像的缩放因子。可以通过设置旋转中心,缩放因子,以及缩放因子来防止旋转后超出边界的问题。OpenCV中逆时针旋转,角度大小为正。

四、仿射变换


原图中所有的平行线在结果图像中同样平行。为了创建这个矩阵我们需要在原图像中找到三个点,以及它们在输出图像中的位置,然后cv.getAffineTransform会创建一个2*3的矩阵,这个矩阵传给cv.warpAffine()得到旋转后的图像。


#仿射变换
def warpaffine_demo(img):
    rows, cols = img.shape[:2]
    #在原图像上的坐标
    pts1 = np.float32([[50,50],[200,50],[50,200]])
    #在输出图像上的坐标
    pts2 = np.float32([[10,100], [200, 50], [100, 250]])

    #会创建一个2x3的矩阵
    M = cv.getAffineTransform(pts1, pts2)
    dst = cv.warpAffine(img, M, (cols, rows))

    cv.imshow('dst', dst)



OPENCV 计算一条直线角度_仿射变换_06


函数warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None),


src是输入图像,


M是2x3的变换矩阵,


dsize是输出图像指定尺寸,


flags:插值算法标识符,默认值为INTER_LINEAR


OPENCV 计算一条直线角度_缩放_07


borderMode:边界像素模式,默认值为BORDER_CONSTANT


borderValue:边界取值,默认值为0


五、透视变换


在变换前后直线还是直线。要构建这个矩阵,需要在输入图像上找到4个点,以及它们在输出图像上对应的位置。这四个点中的任意三个不能共线。


#透视变换
def perspective_demo(img):
    rows, cols = img.shape[:2]
    #输入图像上的四个点,任意三个点不能共线
    pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
    #输出图像上的四个点
    pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])

    M = cv.getPerspectiveTransform(pts1, pts2)
    print(M)
    dst = cv.warpPerspective(img, M, (300, 300))
    cv.imshow('perspective', dst)


OPENCV 计算一条直线角度_仿射变换_08