最近apply了新的算法, 并且更新在了github的主页上面
在youtube上也有效果展示链接
文章中描述的算法是以前的版本, 太长了没空改, 后面空了会更新文章. 新算法的具体实现可以直接去看代码.
这篇文章主要解决这样一个问题:
有一张倾斜了的图片(当然是在Z轴上也有倾斜,不然直接旋转得了o(╯□╰)o),如何尽量将它纠正到端正的状态。
而要解决这样一个问题,可以用到透视变换。
关于透视变换的原理,网上已经有一大推了,这里就不再做介绍了。
这篇文章的干货是:
对OpenCV晦涩难懂的透视变换接口的使用细节的描述;
基于两套自己提出的自动选择顶点进行透视变换的可以运行的
关于干货的第1点,相信很多同学在使用OpenCV透视变换接口的时候,一定google了不少东西吧。。。
而关于干货的第2点,应该更能引起大家的共鸣吧。就像我当初想做这个的时候,信心满满地去搜了很多博客,然而发现绝大部分博客或者教程中,关于透视变换的举例无非是如下两种:
是把一张端正的图像进行扭曲,比如下面这样:
可以说对要做的工作毫无卵用。。。
把上图中变换后的图片恢复成原图。look here
可以说刚看到可以这样子的时候,大家应该是非常激动的。。。赶紧去看看代码里面用了什么方法,然后看啊看,发现仿射变换的4个关键点是手动确定的。。。又可以说毫无卵用了。。毕竟每张图片都要通过手动的方法来确定4个关键点,还是很容易让人崩溃的。。。
于是乎,我决定,自己设计一套算法,来自动确定这4个关键点的坐标。当然,由于才疏学浅,我的这套算法当然可谓是漏洞百出,权当抱砖引玉,欢迎大家提出更好的思路,一起交流~~
干货来啦~~~
OpenCV的透视变换接口
API:
void warpPerspective(InputArray src,
OutputArray dst,
InputArray M,Size dsize,
intflags=INTER_LINEAR,
int borderMode=BORDER_CONSTANT,
const Scalar&borderValue=Scalar()
)
参数含义:
InputArray src:输入的图像;
OutputArray dst:输出的图像;
InputArray M:透视变换的矩阵;
Size dsize:输出图像的大小;
int flags=INTER_LINEAR:输出图像的插值方法。
其中的透视变换矩阵还需要函数findHomography的计算来得到一个单映射矩阵。findHomography的函数接口如下:
Mat findHomography(InputArray srcPoints,
InputArray dstPoints,
int method=0,
doubleransacReprojThreshold=3,
OutputArray mask=noArray()
)
参数含义:
InputArray srcPoints:输入图像的顶点;
InputArray dstPoints:输出图像的顶点。
关于自动计算仿射变换顶点的两种算法实现
以下处理的原图如下:
基于边缘提取
在OpenCV中,表示直线的数据结构一般是Vec4i,这本身是一个vector[1]结构,包含了4个元素,分别对应直线起点和终点的横纵坐标,在工程代码里,用vector来表示经过直线提取后的的直线簇:
vector lines;
首先,对原图进行边缘检测,为了