图片矫正

一、透视变换       

        在平面图片处理时,因为镜头角度等原因,容易导致图像出现倾斜、变形等情况。为了方便后续处理常常需要进行图像矫正,其中主要技术原理是两种变换类型--仿射变换(Affine Transformation)和透视变换(Perspective Transformation)。

        仿射变换是二维坐标间的线性变换, 故而变换后的图像仍然具有原图的一些性质,包括“平直性”以及“平行性”,常用于图像翻转(Flip)、旋转(Rotations)、平移(Translations)、缩放(Scale operations)等,具体到代码应用可以参见OpenCV官方介绍。

        但是仿射变换不能矫正一些变形,如矩形区域的部分发生变化最终变成梯形,这时候矫正就需要用到透视变换。透视变换(Perspective Transformation),又称投影映射(Projective Mapping)、投射变换等,是三维空间上的非线性变换,可看作是仿射变换的更一般形式,简单讲即通过一个3x3的变换矩阵将原图投影到一个新的视平面(Viewing Plane),在视觉上的直观表现就是产生或消除了远近感。落实到OpenCV,图像的透视变换由以下函数完成(该函数是针对图像的包装,其本质调用cv.perspectiveTransform()  进行向量坐标的变换)。

1. 透视变换测试:

1)梯形矫正

2)任意形状矫正

2. 两个关键函数:

1)cv2.findHomography(src[] , dst[])

        返回一个 3 × 3 的变换矩阵。其中, src[] 是原图片的顶点坐标,dst[] 是处理后图片的顶点坐标);

2)dstD = cv2.warpPerspective(imD, H, ( dstD.shape[1] , dstD.shape[0] ) ) 

        得到矫正后的图片。其中,imD 是原始图片,H 是变换矩阵, dstD.shape[1] 和 dstD.shape[0] 是输出图片的宽和高。

3. 问题

        原始图片顶点和输出图片的顶点是手动指定的,不能自动识别。

4. 目的

        得到变换所需要的原始图片中的四个顶点的坐标。

5. 提出想法

1)用凸包多边形拟合为外接四边形,然后求四边形的顶点;

2)角点检测,筛选最上(下、左、右)的顶点作为变换的顶点;

3)霍夫线检测求交点:检测图片文本的边界直线,求到交点作为变换的顶点。

二、将文本区域轮廓拟合为四边形

1. 思路

1)二值化图像;

2)边缘检测;

3)筛选轮廓;

4)轮廓拟合。

2. 测试一

1)边缘检测:

2)轮廓收集:

3)轮廓绘制: 

4)轮廓拟合:

3. 测试二

1)边缘检测:

2) 轮廓收集:

3) 轮廓绘制:

4) 轮廓拟合:

4. 问题:

1)拟合四边形不成功;

2)边界不明显和边界不完整对效果影响较大。

三、角点检测

        角点通常被定义为两条边的交点,或者说,角点的局部邻域应该具有两个不同区域的不同方向的边界。角点检测(Corner Detection)是计算机视觉系统中获取图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维重建和目标识别等,也可称为特征点检测。

1. 角点检测算法的基本思想

        使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。

        目前,角点检测算法还不是十分完善,许多算法需要依赖大量的训练集和冗余数据来防止和减少错误的特征的出现。对于角点检测算法的重要评价标准是:其对多幅图像中相同或者相似特征的检测能力,并且能够应对光照变化、或者图像旋转等影响。
 

2. 关于角点的具体描述可以有几种:

1)一阶导数(即灰度的梯度)的局部最大所对应的像素点;

2)两条及两条以上边缘的交点;

3)图像中梯度值和梯度方向的变化速率都很高的点; 

4)角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。                                                                                     

3. 角点检测算法:

1)基于二值图像的角点检测;

2)基于轮廓曲线的角点检测;

3)基于灰度图像的角点检测:基于梯度、基于模板和基于模板和梯度组合三类方法;常见的基于模板的角点检测算法有:Kitchen-Rosenfeld角点检测算法,Harris角点检测算法,KLT角点检测算法及SUSAN角点检测算法。基于模板的方法主要是考虑像素领域点灰度的变化,即亮度的变化。

4. API:

cornerHarris( InputArray src,                //输入8bit单通道灰度Mat矩阵
		      OutputArray dst,               //用于保存Harris角点检测结果,32位单通道,大小与src相同
	      	  int blockSize,                 //滑块窗口的尺寸,一般取 2
			  int ksize,                     //Sobel边缘检测滤波器大小,一般取 3
			  double k,                      //Harris中间参数,一般取 0.04~0.06
			  int borderType=BORDER_DEFAULT  //插值类型
			 );

5. 测试:

1)有完整边界

2)边界不完整

 

6. 问题:

1)角点检测的精度不高,尤其是边界不明显的时候;

2)边界不完整的时候,角点检测结果无法满足图片矫正的需求。

四、总结

        基于顶点矫正的思路对于原始图片的边界有较高的要求(完整且清晰)。

        上面测试的两张图片在有边界(虽然边界不完美)的情况下不能矫正图片,并且还要考虑以下类型图片,可能要改变一下思路。

猜你喜欢

转载自blog.csdn.net/qq_40206924/article/details/127786774