近期任务
实现对表格照片内容的识别算法。
我的分工:利用python的opencv库实现对照片中的表格的校正,并与小组成员进行代码整合与测试。
一、初步分析
拍照时因为镜头角度等原因,容易导致图像出现倾斜、变形等情况,为了方便后续处理我们常常需要进行图像矫正,其中主要技术原理是两种变换类型–仿射变换(Affine Transformation)和透视变换(Perspective Transformation)。本程序主要使用opencv技术实现图像识别之前的透视变换。
二、思路与部分代码
首先对图像做简单处理方便得到轮廓:
# 灰度
img = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
black = np.zeros(img.shape, np.uint8)
# 高斯模糊
img = cv2.GaussianBlur(img, (5, 5), 0, 0)
# 膨胀
element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
img = cv2.dilate(img, element)
# 轮廓
img = cv2.Canny(img, 20, 40, 3)
# 外轮廓
img, contours, hierarchy = cv2.findContours(
img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# 最大面积的外轮廓
max_area = 0
index = 0
for i in range(0, len(contours)):
ps = contours[i].reshape(len(contours[i]), 2)
r = cv2.boundingRect(ps)
# print r
temparea = r[2] * r[3]
if temparea > max_area:
index = i
max_area = temparea
ct1 = contours[index]
通过轮廓得到顶点,难点是如何选出长方形四个角点
部分代码如下:
# 1.合并线,2.找距离很近的线
lines = []
fclock = [False]
if len(contours2) != 4:
hull = cv2.convexHull(contours2, clockwise=5)
# c4 = contours2.reshape(len(contours2), 2)
c4 = hull.reshape(len(hull), 2)
lines = pstolines(c4)
drawlines(img.shape, lines)
lines = removebadline(lines)
drawlines(img.shape, lines)
if len(lines) != 4 and len(lines) != 0:
lines = removemoreline(lines, fclock)
print
"fclock=", fclock
if len(lines) != 4 and len(lines) != 0:
fclock = [False]
lines = hulllines(lines)
lines = removemoreline(lines, fclock)
if len(lines) != 4 and len(lines) != 0:
for i in range(0, len(lines)):
cv2.circle(black, (lines[i][0], lines[i][1]), 3, (128), 2)
cv2.line(black, (lines[i][0], lines[i][1]), (lines[i][2], lines[i][3]), (128), 1)
cv2.putText(black, str(i), (lines[i][0], lines[i][1]),
cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))
#cv2.imshow("2", black)
cv2.circle(black, (lines[len(lines) - 1][0],
lines[len(lines) - 1][1]), 3, (128), 2)
cv2.putText(black, str(len(lines)), (lines[len(lines) - 1][0], lines[len(lines) - 1][1]),
cv2.FONT_HERSHEY_TRIPLEX, 0.4, (255))
透视变换技术学习
摘自百度百科:
透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
经过了解:
在OpenCV中,仿射变换和透视变换均有封装好的函数,分别为
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
与
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:输出变换后图像,需要初始化一个空矩阵用来保存结果,不用设定矩阵尺寸
参数InputArray M:变换矩阵,用另一个函数getAffineTransform()计算
参数Size dsize:设置输出图像大小
参数int flags=INTER_LINEAR:设置插值方式,默认方式为线性插值
仿射变换以3个点为基准点,即使数组长度为4也仅取前3个点作为基准点;透视变换以4个点为基准点,两种变换结果不相同。
目前计划使用透视变换处理图片。