1. 最近在做身份证OCR项目中,需要对倾斜扭曲的图像做矫正,透视变换正可以解决这个问题,在这里记录对变换方法的理解。
2. 本文主要介绍一下仿射变换和透视变换的原理,特点以及其在opencv中实现的一些注意点。
3. 首先看下透视变换后的例图:
透视变换和仿射变换在原理上比较相似,而仿射变换更加简单。
1. 定义:仿射变换(Affine Transformation或 Affine Map),又称为仿射映射,是指在几何中,图像进行从一个向量空间进行一次线性变换和一次平移,变换为到另一个向量空间的过程。
2. 特性:仿射变换保持了二维图形的平直性和平行性。平直性:变换是直线的,变换后还是直线;平行性:二维图形之间的相对位置关系保持不变。
3. 公式:如图所示
其中,
4. 理解:
在几何中,任何变换都可以以矩阵乘法(线性变换)的形式表示,图像中的平移操作可以以矢量加法(平移)的形式表示;
5. 应用:
有了仿射变换的理解,下面说透视变换就简单了,因为它是仿射变换的一种非线性扩展。
1. 定义:透视变换(Perspective Transformation)就是将图片投影到一个新的视平面,也称为投影映射。
2. 特性:相对仿射变换来说,改变了直线之间的平行关系。
3. 直接看公式:通用的变换公式如下
其中,
4. 理解:
5. 应用:
6. 代码:
# 身份证的模版技术
import cv2
import numpy as np
import os
from matplotlib import pyplot as plt
from math import *
img_path = ""
img = cv2.imread(img_path, 0)
print("原图")
plt.imshow(img, cmap='gray', interpolation='bicubic')
plt.show()
txt_path = img_path.split('.')[0] + '.txt'
# Roi顺时针坐标
with open(txt_path, encoding='utf-8') as f:
rec = list(map(float, f.readline().strip().split(',')))
# print(rec)
xDim, yDim = img.shape[1], img.shape[0]
pt1 = (max(1, rec[0]), max(1, rec[1]))
pt2 = (rec[2], rec[3])
pt3 = (rec[4], rec[5])
pt4 = (min(rec[6], xDim - 2), min(yDim - 2, rec[7]))
pts = np.array([pt1, pt2, pt3, pt4], np.int32)
H_rows, W_cols= 400, 600
# print(H_rows, W_cols)
# 原图中书本的四个角点(左上、右上、左下、右下),与变换后矩阵位置
pts1 = np.float32([pt1, pt2, pt3, pt4])
pts2 = np.float32([[0, 0],[W_cols,0],[W_cols, H_rows],[0, H_rows],])
# 生成透视变换矩阵;进行透视变换
M = cv2.getPerspectiveTransform(pts1, pts2)
# print(M)
dst = cv2.warpPerspective(img, M, dsize=(W_cols,H_rows))
print("校正之后的图")
plt.imshow(dst, cmap='gray', interpolation='bicubic')
plt.show()