网站建设与管理课程代码,建设银行辽宁分行报名网站,网站子站点是什么意思,第三方做网站图像透视转换简介
在 OpenCV 里#xff0c;图像透视转换属于重要的几何变换#xff0c;也被叫做投影变换。下面从原理、实现步骤、相关函数和应用场景几个方面为你详细介绍。
原理 实现步骤
选取对应点#xff1a;要在源图像和目标图像上分别找出至少四个对应的点。这些对…图像透视转换简介
在 OpenCV 里图像透视转换属于重要的几何变换也被叫做投影变换。下面从原理、实现步骤、相关函数和应用场景几个方面为你详细介绍。
原理 实现步骤
选取对应点要在源图像和目标图像上分别找出至少四个对应的点。这些对应点不能共线因为它们是计算透视变换矩阵的关键依据。计算透视变换矩阵利用 OpenCV 的 cv2.getPerspectiveTransform 函数依据前面选取的对应点来计算透视变换矩阵。应用透视变换使用 cv2.warpPerspective 函数将计算得到的透视变换矩阵应用到源图像上从而得到透视变换后的图像。
相关函数
cv2.getPerspectiveTransform 功能计算透视变换矩阵。语法cv2.getPerspectiveTransform(src, dst)参数 src源图像中四个点的坐标数据类型为 np.float32。dst目标图像中对应的四个点的坐标数据类型为 np.float32。 返回值返回一个 3×3 的透视变换矩阵。cv2.warpPerspective 功能对图像应用透视变换。语法cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])参数 src源图像。M透视变换矩阵。dsize输出图像的大小格式为 (width, height)。dst可选输出图像。flags可选插值方法如 cv2.INTER_LINEAR 等。borderMode可选边界填充模式。borderValue可选边界填充值。 返回值返回透视变换后的图像。
应用场景
图像校正校正因拍摄角度倾斜而产生畸变的图像例如校正拍摄的文档图像使其呈现为标准的矩形。虚拟现实在虚拟现实场景中将二维图像转换为具有透视效果的三维场景增强沉浸感。自动驾驶对车载摄像头拍摄的图像进行透视变换以获取道路的鸟瞰图辅助车辆进行路径规划和障碍物检测。
图像透视转换实例 对以下图片进行图像透视转换 实例步骤
导入所需库
import numpy as np
import cv2写入所需函数
def resize(image, widthNone, heightNone, intercv2.INTER_AREA):# 初始化 dim 为 None用于存储调整后的图像尺寸dim None# 获取图像的高度和宽度(h, w) image.shape[:2]# 如果宽度和高度都未指定直接返回原图像if width is None and height is None:return image# 如果仅指定了高度计算宽度的缩放比例if width is None:r height / float(h)dim (int(w * r), height)# 如果仅指定了宽度计算高度的缩放比例else:r width / float(w)dim (width, int(h * r))# 使用 cv2.resize 函数根据 dim 和指定的插值方法对图像进行缩放resized cv2.resize(image, dim, interpolationinter)# 返回缩放后的图像return resized# 定义一个函数用于显示图像
# name: 显示窗口的名称
# img: 要显示的图像
def cv_show(name,img):# 使用cv2.imshow函数显示图像第一个参数是窗口名称第二个参数是要显示的图像cv2.imshow(name,img)# 使用cv2.waitKey(0)等待用户按键参数为0表示无限等待cv2.waitKey(0)# 定义一个函数用于对输入的四个点进行排序
# pts: 输入的四个点的坐标是一个形状为(4, 2)的numpy数组
def order_points(pts):# 创建一个形状为(4, 2)的全零数组数据类型为float32用于存储排序后的点rect np.zeros((4,2),dtypefloat32)# 计算每个点的x和y坐标之和s pts.sum(axis1)# 找到坐标和最小的点这个点通常是左上角的点rect[0]pts[np.argmin(s)]# 找到坐标和最大的点这个点通常是右下角的点rect[2]pts[np.argmax(s)]# 计算每个点的x和y坐标之差diff np.diff(pts,axis1)# 找到坐标差最小的点这个点通常是右上角的点rect[1]pts[np.argmin(diff)]# 找到坐标差最大的点这个点通常是左下角的点rect[3]pts[np.argmax(diff)]# 返回排序后的四个点return rect# 定义一个函数用于进行四点透视变换
# image: 输入的原始图像
# pts: 输入的四个点的坐标是一个形状为(4, 2)的numpy数组
def four_point_transform(image,pts):# 调用order_points函数对输入的四个点进行排序rect order_points(pts)# 解包排序后的四个点分别赋值给左上角、右上角、右下角和左下角的点(tl,tr,br,bl) rect# 计算新图像的宽度通过计算右下角和左下角点之间的距离widthA np.sqrt(((br[0]-bl[0])**2)((br[1]-bl[1])**2))# 计算新图像的宽度通过计算右上角和左上角点之间的距离widthB np.sqrt(((tr[0]-tl[0])**2)((tr[1]-tl[1])**2))# 取两个宽度中的最大值作为新图像的宽度maxWidth max(int(widthA),int(widthB))# 计算新图像的高度通过计算右上角和右下角点之间的距离heightA np.sqrt(((tr[0]-br[0])**2)((tr[1]-br[1])**2))# 计算新图像的高度通过计算左上角和左下角点之间的距离heightB np.sqrt(((tl[0]-bl[0])**2)((tl[1]-bl[1])**2))# 取两个高度中的最大值作为新图像的高度maxHeight max(int(heightA),int(heightB))# 创建一个形状为(4, 2)的numpy数组用于存储变换后的四个点的坐标dst np.array([[0,0],[maxWidth-1,0],[maxWidth-1,maxHeight-1],[0,maxHeight-1]],dtypefloat32)# 使用cv2.getPerspectiveTransform函数计算透视变换矩阵M cv2.getPerspectiveTransform(rect,dst)# 使用cv2.warpPerspective函数进行透视变换得到变换后的图像warped cv2.warpPerspective(image,M,(maxWidth,maxHeight))# 返回变换后的图像return warped获取图片信息并处理图片
import cv2# 读取指定路径的图片返回一个表示图像的多维数组
image cv2.imread(dan_zi.jpg)
# 调用自定义的cv_show函数展示原始图像窗口名为image
cv_show(image, image)# 计算原始图像高度与500像素的比例后续用于恢复尺寸
ration image.shape[0] / 500.0
# 复制原始图像避免后续操作修改原始数据
orig image.copy()
# 调用resize函数将图像高度调整为500像素保持宽高比
image resize(orig, height500)
# 调用cv_show函数展示调整大小后的图像窗口名为1
cv_show(1, image)# 打印提示信息表明进入轮廓检测步骤
print(STEP 1: 轮廓检测)
# 将调整大小后的图像从BGR颜色空间转换为灰度颜色空间
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 运用Otsus算法进行二值化处理得到二值化后的图像
edged cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# 在二值化图像的副本上查找轮廓使用RETR_LIST检索模式和CHAIN_APPROX_SIMPLE近似方法
cnts cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]
# 在图像副本上绘制所有检测到的轮廓颜色为红色线条宽度为1像素
image_contours cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 1)
# 调用cv_show函数展示绘制了所有轮廓的图像窗口名为image_contours
cv_show(image_contours, image_contours)# 打印提示信息表明进入获取最大轮廓步骤
print(STEP 2:获取最大轮廓)
# 按轮廓面积从大到小对检测到的轮廓进行排序选取面积最大的轮廓
screenCnt sorted(cnts, keycv2.contourArea, reverseTrue)[0]# 计算最大轮廓的周长参数True表示轮廓是封闭的
peri cv2.arcLength(screenCnt, True)
# 对最大轮廓进行多边形逼近以减少轮廓上的点数第二个参数为逼近精度
screenCnt cv2.approxPolyDP(screenCnt, 0.02 * peri, True)
# 打印逼近后轮廓的形状信息
print(screenCnt.shape)# 在图像副本上绘制逼近后的最大轮廓颜色为绿色线条宽度为2像素
image_contour cv2.drawContours(image.copy(), [screenCnt], -1, (0, 255, 0), 2)# 展示绘制了最大逼近轮廓的图像窗口名为image_contour
cv2.imshow(image_contour, image_contour)
# 等待用户按键防止窗口立即关闭
cv2.waitKey(0)进行透视转换
# 调用之前定义的 four_point_transform 函数对原始图像进行四点透视变换
# screenCnt.reshape(4, 2) * ration 是将之前获取的轮廓点恢复到原始图像的尺寸
warped four_point_transform(orig, screenCnt.reshape(4, 2) * ration)
# 将透视变换后的图像保存为 invoice_new.jpg
cv2.imwrite(invoice_new.jpg, warped)
# 创建一个名为 xxxxx 的窗口并且该窗口大小可以调整
cv2.namedWindow(xxxxx, cv2.WINDOW_NORMAL)
# 在 xxxxx 窗口中显示透视变换后的图像
cv2.imshow(xxxxx, warped)
# 等待用户按键防止窗口立即关闭
cv2.waitKey(0)# 将透视变换后的图像从 BGR 颜色空间转换为灰度颜色空间
warped cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
# 调用 resize 函数将灰度图像的宽度调整为 400 像素
warped resize(warped, 400)
# 对调整大小后的灰度图像使用 Otsus 算法进行二值化处理
warped cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# 调用自定义的 cv_show 函数显示二值化后的图像窗口名为 1111
cv_show(1111, warped)# 创建一个 1x1 的矩形结构元素用于形态学操作
rectKernel cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1))
# 对二值化后的图像进行闭运算填充小孔和连接相邻物体
closeX cv2.morphologyEx(warped, cv2.MORPH_CLOSE, rectKernel)
# 调用自定义的 cv_show 函数显示闭运算后的图像窗口名为 gradX
cv_show(gradX, closeX)结果显示 invoice_new.jpg 如果不想使用这张照片换其他图片也是可以的处理步骤都是相同的