Python中OpenCV透视变换恢复扭曲图像
在处理图像问题时,经常会遇到将要处理的目标的位置是斜的,需要使用透视变换进行矫正。如下图,该图片中左边的目标是扭曲倾斜拍摄的,那么任务就是将其矫正过来,如下图右图所示。
文章来源:https://www.toymoban.com/news/detail-808863.html
方法
- 前提1:这里假设我已经知道四个点坐标(可用深度学习方法检测/分割)和目标宽高比(比如身份证、驾驶证、发票等有固定宽高比)
- 基本流程:
- 1、计算变换矩阵
getPerspectiveTransform
- 2、透视变换
warpPerspective
- 1、计算变换矩阵
- 一些理论可参考:https://zhuanlan.zhihu.com/p/36082864
函数接口简介
# 变换矩阵函数
Mat getPerspectiveTransform(const Point2f* src, const Point2f* dst)
# 参数const Point2f* src:原图的三个固定顶点
# 参数const Point2f* dst:目标图像的三个固定顶点
# 返回值:Mat型变换矩阵,可直接用于warpPerspective()函数
# 注意,顶点数组长度超过4个,则会自动以前4个为变换顶点;数组可用Point2f[]或Point2f*表示
# 透视变换函数
void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
# 参数InputArray src:输入变换前的图像;
# 参数OutputArray dst:输出变换后图像,需要初始化一个空矩阵用来保存结果,不用设定矩阵尺寸;
# 参数Size dsize:设置输出图像大小;
# 参数int flags=INTER_LINEAR:设置插值方式,默认方式为线性插值;
代码
def get_rotate_crop_image(img, points):
'''
img_height, img_width = img.shape[0:2]
left = int(np.min(points[:, 0]))
right = int(np.max(points[:, 0]))
top = int(np.min(points[:, 1]))
bottom = int(np.max(points[:, 1]))
img_crop = img[top:bottom, left:right, :].copy()
points[:, 0] = points[:, 0] - left
points[:, 1] = points[:, 1] - top
'''
assert len(points) == 4, "shape of points must be 4*2"
img_crop_width = int(
max(
np.linalg.norm(points[0] - points[1]),
np.linalg.norm(points[2] - points[3])))
img_crop_height = int(
max(
np.linalg.norm(points[0] - points[3]),
np.linalg.norm(points[1] - points[2])))
pts_std = np.float32([[0, 0], [img_crop_width, 0],
[img_crop_width, img_crop_height],
[0, img_crop_height]])
M = cv2.getPerspectiveTransform(points, pts_std)
dst_img = cv2.warpPerspective(
img,
M, (img_crop_width, img_crop_height),
borderMode=cv2.BORDER_REPLICATE,
flags=cv2.INTER_CUBIC)
return dst_img
if __name__ == '__main__':
img_path = '../images/trans/test01.jpg'
img = cv2.imread(img_path)
# 四个定点左边
points = [180, 160, 656, 152, 760, 414, 86, 428]
# 行驶证比例:102/73
points = np.array(points).astype(np.float32).reshape(4, 2)
partImg = get_rotate_crop_image(img, points)
height, width, _ = partImg.shape
cv2.imwrite('text01.jpg', partImg)
# 最长边为长边,resize图片
new_height = int(width * 73/102)
partImg = cv2.resize(partImg,(width, new_height))
cv2.imwrite('text.jpg', partImg)
完整结果
文章来源地址https://www.toymoban.com/news/detail-808863.html
到了这里,关于Python中OpenCV透视变换恢复扭曲图像的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!