3小时精通opencv(四) 透视变换与图像拼接

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

3小时精通opencv(四) 透视变换与图像拼接

参考视频资源:3h精通Opencv-Python

文章目录


透视变换

透视变换建立两平面场之间的对应关系 将原始图片投影到一个新的视平面上

# Author    : JokerTong
# Datetime  : 2023-01-16 14:41
# File      : chapter5.py
import cv2
import numpy as np

img = cv2.imread('Resources/cards.jpg')

width, height = 250, 350
src = np.float32([[111, 219], [287, 188], [154, 482], [352, 440]])
dst = np.float32([[0, 0], [width, 0], [0, height], [width, height]])
matrix = cv2.getPerspectiveTransform(src, dst)
imgOutput = cv2.warpPerspective(img, matrix, (width, height))

cv2.imshow('Image', img)
cv2.imshow('Output', imgOutput)
cv2.waitKey(0)

主要使用cv2.getPerspectiveTransformcv2.warpPerspective两个函数

  • cv2.getPerspectiveTransform根据图像中不共线的 4 个点在变换前后的对应位置求得 (3x3) 变换矩阵
  • cv2.warpPerspective使用该 (3x3) 变换矩阵即可求出变换后的图像。
    在这里插入图片描述
  • cv2.getPerspectiveTransform: 得到变换矩阵
    • src : 变换前图像四边形顶点坐标
    • dst: 变换后图像四边形顶点坐标

在这里插入图片描述

  • cv2.warpPerspective: 得到变换后的图片
    • src : 原始输入图像
    • M: 用getPerspectiveTransform求得的变换矩阵
    • dsize 输出图像的大小 width, height)

在这里插入图片描述

图像拼接

# Author    : JokerTong
# Datetime  : 2023-01-16 14:59
# File      : chapter6.py
import cv2
import numpy as np

img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 用numpy来拼接, 无法改变图像的大小, 并且channel相同才可以拼接
imgHor = np.hstack((img, img))
# imgHor = np.hstack((img, imgGray))  # 会发生报错 因为维度不同
imgVer = np.vstack((img, img))

cv2.imshow("Horizontal", imgHor)
cv2.imshow("Vertical", imgVer)
cv2.waitKey(0)

读入的img可以看成一个矩阵, 所以可以用numpy的函数来对矩阵进行拼接
但这样有着许多局限性 如图像太大超出显示范围, 只能对相同维度的进行拼接(彩色和灰色不能拼接)

在这里插入图片描述
这里引入一个函数stackImages, 只需要知道怎么使用就行

def stackImages(scale, imgArray):
    '''
    完成图像拼接的操作
        若横着拼接, 则imgArray为 ([img,img,img])
        若竖着拼接, 则imgArray为 ([img], [img], [img])
    :param scale: 对原始图像放大缩小的比例
    :param imgArray: 要拼接的图像数组
    :return: 拼接完的图像
    '''

案例

# Author    : JokerTong
# Datetime  : 2023-01-16 14:59
# File      : chapter6.py
import cv2
import numpy as np


def stackImages(scale, imgArray):
    '''
    完成图像拼接的操作
        若横着拼接, 则imgArray为 ([img,img,img])
        若竖着拼接, 则imgArray为 ([img], [img], [img])
    :param scale: 对原始图像放大缩小的比例
    :param imgArray: 要拼接的图像数组
    :return: 拼接完的图像
    '''
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver


img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 用stackImages函数来进行拼接
imgStack1 = stackImages(0.5, ([img, imgGray, img], [img, img, img]))
imgStack2 = stackImages(0.5, ([img, imgGray, img]))
imgStack3 = stackImages(0.5, ([img], [img], [img]))
cv2.imshow('ImageStack1', imgStack1)
cv2.imshow('ImageStack2', imgStack2)
cv2.imshow('ImageStack3', imgStack3)
cv2.waitKey(0)

可以按行 按列 并且不同维度的拼接, 也可以修改图像显示时的大小

在这里插入图片描述

全部代码

# Author    : JokerTong
# Datetime  : 2023-01-16 14:59
# File      : chapter6.py
import cv2
import numpy as np


def stackImages(scale, imgArray):
    '''
    完成图像拼接的操作
        若横着拼接, 则imgArray为 ([img,img,img])
        若竖着拼接, 则imgArray为 ([img], [img], [img])
    :param scale: 对原始图像放大缩小的比例
    :param imgArray: 要拼接的图像数组
    :return: 拼接完的图像
    '''
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range(0, rows):
            for y in range(0, cols):
                if imgArray[x][y].shape[:2] == imgArray[0][0].shape[:2]:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
                else:
                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]),
                                                None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y] = cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = np.zeros((height, width, 3), np.uint8)
        hor = [imageBlank] * rows
        hor_con = [imageBlank] * rows
        for x in range(0, rows):
            hor[x] = np.hstack(imgArray[x])
        ver = np.vstack(hor)
    else:
        for x in range(0, rows):
            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
            else:
                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = np.hstack(imgArray)
        ver = hor
    return ver


img = cv2.imread('Resources/lena.png')
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# # 用numpy来拼接, 无法改变图像的大小, 并且channel相同才可以拼接
# imgHor = np.hstack((img, img))
# # imgHor = np.hstack((img, imgGray))  # 会发生报错 因为维度不同
# imgVer = np.vstack((img, img))
# 
# cv2.imshow("Horizontal", imgHor)
# cv2.imshow("Vertical", imgVer)
# cv2.waitKey(0)

# 用stackImages函数来进行拼接
imgStack1 = stackImages(0.5, ([img, imgGray, img], [img, img, img]))
imgStack2 = stackImages(0.5, ([img, imgGray, img]))
imgStack3 = stackImages(0.5, ([img], [img], [img]))
cv2.imshow('ImageStack1', imgStack1)
cv2.imshow('ImageStack2', imgStack2)
cv2.imshow('ImageStack3', imgStack3)
cv2.waitKey(0)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6