实现步骤实际上很简单,只需要三步:
第一步:查找文档的边缘
第二步:通过边缘查找文档轮廓并找到四个角点的坐标
第三步:使用透视转换函数完成图像转换
下面的代码基于openCV/python的版本:openCV2.4/3+, python2.7/3+
上一章节我们完成了transform.py模块的构建,我们将在接下来的涉及图像四角点处理的问题中均会使用到。打开你的python编辑器,创建一个新的文档,并命名为scan.py。
接下来就是第一步:边缘查找:
测试一下效果:
shell
虽然背景有点不干净但是文档的边缘还是很明显的,接下来我们想办法查找文档的边缘并生成轮廓。
第二步:寻找轮廓:
事实上,在构建文档扫描器时,有一个非常重要的前提:扫描仪只是在一张纸上扫描。一张纸被假定为长方形,矩形有四条边。因此,我们可以创建一个简单的方法来帮助我们构建文档扫描器。我们假设图像中最大的轮廓恰好有四个点,这就是我们要扫描的那张纸。这也是一个相当安全的假设——当然,也可以人为的给定文档轮廓。
运行一下代码测试效果:shell中输入
正如您所看到的,我们已经成功地利用边缘检测图像找到了文档的轮廓(outline),我的收据周围的绿色矩形显示了轮廓(outline)。最后,让我们进入步骤3,这将是用到four_point_transform函数。
第三步:转换图像:构建移动文档扫描器的最后一步是取代表文档大纲的四个点,并应用透视图转换来获得自顶向下的图像“鸟瞰图”。
我们将把两个参数传递给four_point_transform:第一个参数是我们从磁盘加载的原始图像(不是调整大小的图像),第二个参数是表示文档的轮廓线,乘以调整大小的比例。
你可能会想,为什么要乘以调整后的比例? 我们乘以调整后的比例,因为我们进行了边缘检测,在调整后的高度=500像素的图像上发现了轮廓。但是,我们希望对原始图像进行扫描,而不是对调整大小的图像进行扫描,因此我们将轮廓点乘以调整大小的比例。
为了获得图像的黑白感觉,我们将扭曲后的图像转换为灰度图像,并应用自适应阈值。
好的,我们来运行一下效果:
shell
好了,到目前为止,扫描图像到文档提取鸟瞰图的过程实现完成了。遗留问题:
实际上这个程序还有不少地方需要你的改进,比如要求转换的文档本身是规则的四边形,拍摄时尽量放在对比度明显的桌面背景,这样做的目的是为了避免边缘查找时出现多于四边的情况,多于四边的边缘后续轮廓查找会出现问题。也就是找不到合适的四边轮廓来匹配。
解决方案:可以采用人工标注四个角点的方式来提取轮廓更为可靠。因为在实际应用场景往往是不规则的文档。下一节我们来探讨这个方案实现过程。
//将标记处改成如下即可:#include "stdafx.h"
//#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>
using namespace cv
int main(int argc,char** argv)
{
IplImage *src=cvLoadImage("D:\\Lena.jpg",0)
if(src==NULL)
{
return 0
}
cvNamedWindow("src", CV_WINDOW_AUTOSIZE)
cvShowImage("src", src)
IplImage *dst1_img=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1)
cvSmooth (src, dst1_img, CV_GAUSSIAN, 11, 0, 0, 0)
cvNamedWindow ("Gaussian", CV_WINDOW_AUTOSIZE)
cvShowImage ("Gaussian", dst1_img)
IplImage *adaptive_img = cvCreateImage(cvGetSize(dst1_img),IPL_DEPTH_8U,1)
cvAdaptiveThreshold(dst1_img, adaptive_img, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 7, 8)//函数改成这样即可
cvNamedWindow ("adaptive", CV_WINDOW_AUTOSIZE)
cvShowImage ("adaptive", adaptive_img)
waitKey()
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)