opencv 表格识别之表格透视矫正(二)

上一篇文章中给出了一种对表格进行矫正的方法,但是只能用于只有一个表格的情况,对于有多个表格的情况的矫正的方法,将在这篇文章中给出。

单个表格矫正:链接

一, 函数的介绍

(1)Homography(.....)函数返回映射关系H(3*3的矩阵)
 

CV_EXPORTS_W Mat findHomography( 
				InputArray srcPoints, 
				InputArray dstPoints,
                                int method=0, 
                                double ransacReprojThreshold=3,
                                OutputArray mask=noArray());

srcPoints,dstPoints是两视图中匹配的点
method 是计算单应矩阵所使用的方法,是一个枚举值。
ransacReprojThreshold 是允许的最大反投影错误,只在使用RANSAC方法时有效。
mask指出匹配的点是不是离群值,用来优化匹配结果。

在这里,我们只用前两个 参数,也就是待矫正的图像的四个点,与模板图像的四个点(这四个点我们取图像中最大的表格的四个角,因为最大的表格比较好找),找出这两个点的映射关系,再通过warpPerspective(....)函数对待矫正的图像进行H映射。      

(2)warpPerspective(....)对图像进行变换

void warpPerspective(InputArray src, 	//输入图像
 OutputArray dst,			//输出图像 
 lnputArray M,				//透视变换矩阵
 Size dsize, 				//输出图像的大小
 int flags=INTER_LINEAR,	        //输出图像的插值方法
 int borderMode=BORDER_CONSTANT, 	//边界的处理方法
  const Scalar& borderValue=Scalar())	//边界的颜色

透视变换矩阵就是H。

 二,具体步骤

第一张是模板图像,第二张是待矫正的图像,我们要找出模板图像的最大的表格,和待矫正的第图像的最大的表格,然后通过两个最大表格的四个顶点得到映射矩阵。

opencv 表格识别之表格透视矫正(二)_第1张图片

                                                                                               图一

opencv 表格识别之表格透视矫正(二)_第2张图片

                                                                                                图二

        //提取轮廓 
	vector hierarchy;
	std::vector > contours;
	cv::findContours(bw, contours, hierarchy, CV_RETR_LIST, CHAIN_APPROX_SIMPLE);

												//逼近多边形
	vector > contours_poly(contours.size());
        
        //最大的表格的下标和面积
	int indexMax = 0;
	double areaMax = 0;
	for (size_t i = 0; i < contours.size(); i++)
	{
		//面积
		double area = contourArea(contours[i]);

		//筛选可能存在且不代表表的单独的行的行。
		if (area < 20) // value is randomly chosen
			continue;

		//逼近区域成为一个形状
		approxPolyDP(Mat(contours[i]), contours_poly[i], 10, true);

		//找出面积最大的四边形
		if (area > areaMax)
		{
			areaMax = area;
			indexMax = i;
		}
	}
        
        //画出最大的表格的形状
	Scalar color(0, 0, 255);
	drawContours(srcClone, contours, indexMax, color, 1, 8);
	imshow("contou1", srcClone);
	waitKey();

	std::vector  pts_dst;

        //将待矫正的表格的四个顶点按顺时针排序
	sortPoint(contours_poly[indexMax], pts_dst);
	//将模板比表格的四个顶点按照顺时针排序
        sortPoint(pts_src, pts_src);
        
        //得到映射函数
	Mat h = findHomography(pts_dst, pts_src);
        //根据映射函数进行矫正
	warpPerspective(src, dst, h, srcImageSize);

矫正后的表格:

opencv 表格识别之表格透视矫正(二)_第3张图片

相比于第一个方法,这个整体矫正的方法,显然更符合我们项目需要的结果。

 

你可能感兴趣的:(c++,表格提取,opencv)