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。

 二,具体步骤

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

                                                                                               图一

                                                                                                图二

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

												//逼近多边形
	vector<vector<Point2f> > 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<cv::Point2f>  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);

矫正后的表格:

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

 

<think>我们正在处理一个关于Android表格识别实现的问题。根据提供的引用,我们可以提取以下关键信息: 引用[2]提到表格识别接口为表格处理带来新解决方案,引用[1]介绍了Android中表格显示的多种实现方式(特别是ListView),引用[4]则涉及手势识别技术。 用户需求:在Android平台上实现表格识别。 分析: 1. 表格识别通常指从图像中识别表格结构并提取数据。 2. Android平台实现需考虑:图像输入(相机或图库)、图像处理、表格检测与识别、数据输出。 技术方案步骤: 1. 图像获取:使用相机API或图库选择图片。 2. 图像预处理:裁剪、旋转、值化等,优化图像质量。 3. 表格识别:使用OCR技术识别文字,同时检测表格线(或区域)以确定行列结构。 4. 数据结构化:将识别结果转化为结构化数据(如维数组)。 5. 显示与交互:将识别后的表格数据显示在App中(如使用ListView或RecyclerView,引用[1])。 具体实现方式: - 方案1:使用现有SDK(如Google ML Kit的Text Recognition,但需自行扩展表格结构识别)。 - 方案2:集成第三方表格识别API(云端或本地),如ABBYY、Aspose等。 - 方案3:自研算法(适用于特定场景,开发成本高)。 推荐方案: - 对于大多数应用,推荐采用方案1或2。由于表格识别涉及复杂的图像处理和布局分析,自研难度较大。 - 使用Google ML Kit进行文本识别,然后通过算法(如基于空白区域和文本位置)推断表格结构。 实现步骤示例: 1. 添加依赖:在build.gradle中引入ML Kit的文本识别库。 2. 获取图像:启动相机或图库选择图片,获取Bitmap。 3. 文本识别:使用`TextRecognizer`处理图像,获取文本块(`TextBlock`)及其位置。 4. 表格结构分析:根据文本块的位置信息,通过聚类算法(如按y坐标分组为行,再按x坐标排序)构建表格。 5. 显示表格:将识别出的数据填充到ListView或RecyclerView(参考引用[1])。 注意事项: - 表格结构复杂时(如合并单元格),识别难度增加,需设计更复杂的算法。 - 考虑离线(设备端)与在线(云端)识别的选择,离线可使用ML Kit,在线可调用如百度OCR等API。 相关问题: 1. 如何提高Android上表格识别的准确率? 2. 有哪些开源的表格识别库可用于Android? 3. 如何将识别出的表格数据导出为Excel?</think>### Android表格识别技术实现方案 在Android平台上实现表格识别,需要结合图像处理、OCR技术和数据结构化处理。以下是完整的技术方案: #### 1. **图像获取与预处理** - **图像输入**:使用CameraX API获取实时图像或通过`Intent.ACTION_GET_CONTENT`从图库选择图片[^1] - **预处理关键步骤**: - 透视校正:使用OpenCV的`findContours()`检测文档边缘,通过`warpPerspective()`矫正变形 - 值化处理:应用自适应阈值算法(如`adaptiveThreshold()`)增强文本对比度 - 降噪滤波:使用高斯模糊减少图像噪声 ```kotlin // 示例:文档边缘检测 val gray = Mat() Imgproc.cvtColor(inputMat, gray, Imgproc.COLOR_BGR2GRAY) Imgproc.GaussianBlur(gray, gray, Size(5.0, 5.0), 0.0) Imgproc.Canny(gray, edges, 50.0, 150.0) ``` #### 2. **表格结构识别** - **线检测**: - 使用Hough线变换检测表格横纵线 - 线段聚类算法合并相邻线段 - **单元格定位**: - 基于线交叉点生成网格 - 无框表格处理:通过文本块相对位置推断行列(Voronoi图分割) - **合并单元格识别**: - 分析连续空白区域与文本跨度关系 #### 3. **OCR文本识别** - **本地方案**:集成**ML Kit Text Recognition v2**(支持中文,离线运行) ```gradle implementation 'com.google.android.gms:play-services-mlkit-text-recognition:19.0.0' ``` ```kotlin val recognizer = TextRecognition.getClient() recognizer.process(imageInput) .addOnSuccessListener { result -> parseTextBlocks(result.textBlocks) } ``` - **云端方案**(高精度需求):调用百度OCR/Google Vision API,处理复杂表格 #### 4. **数据结构化** - **文本-单元格映射**: ```java class TableCell(val row: Int, val col: Int, val text: String, val rect: Rect) ``` - **表格重建算法**: 1. 按Y坐标分组文本块→行 2. 行内按X坐标排序→列 3. 合并跨行列单元格 #### 5. **结果展示与交互** - 使用`RecyclerView`实现动态表格渲染[^1] - 添加单元格点击事件: ```kotlin viewHolder.itemView.setOnClickListener { showEditDialog(cellData) // 支持修改识别结果 } ``` - 导出功能:生成Excel/CSV文件(使用Apache POI库) #### 6. **性能优化要点** - **异步处理**:通过`WorkManager`调度识别任务,避免主线程阻塞 - **缓存机制**:存储预处理图像,减少重复计算 - **精度-速度权衡**:实时场景用低分辨率图像(720p),精确识别用原图 - **模型裁剪**:使用TensorFlow Lite定制OCR模型(仅保留中文识别层) #### 7. **增强方案** - **手势交互**:集成缩放/平移手势(引用`GestureDetector`[^4]) - **实时预览**:CameraX Analyzer API实现取景框实时表格检测 - **离线支持**:打包Tesseract OCR引擎(需训练中文表格模型) **难点解决方案**: - **倾斜表格**:利用`RotatedRect`计算最小外接矩形旋转角度 - **复杂合并单元格**:采用决策树算法分析文本分布密度 - **手写体识别**:集成MNIST模型+CRNN序列识别 > 提示:对于金融/医疗等专业领域表格,建议采用混合方案——本地快速识别+云端校验,平衡速度与准确率[^2]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值