java-opencv再谈表格识别
前言
图一简单点:
图二复杂点有合并的:
新方式
- 关键点在于Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontalsize,1)) 的size 宽设置1,高设置1,很高级的想法;
- 横线提取方式
int sc = 30; //这个值越大,检测到的直线越多
int horizontalsize = clone.cols() / sc;//宽像素点个数比例
//其实是个卷积核 注意 new Size(horizontalsize,1)宽上面得到的比例、高度设置为1
Mat horizontalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontalsize,1));
//腐蚀
Imgproc.erode(horizontal, horizontal, horizontalStructure, new Point(-1, -1), 1);
//膨胀 背景变大 内容变小
Imgproc.dilate(horizontal, horizontal, horizontalStructure, new Point(-1, -1), 1);
- 竖线提取方式和上面一样
int verticalsize = clone.rows() / sc;//高像素点个数比例
//其实是个卷积核 注意 new Size(horizontalsize,1)宽1、高度上面得到的比例
Mat verticalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1,verticalsize ));
//腐蚀
Imgproc.erode(vertical, vertical, verticalStructure , new Point(-1, -1), 1);
//膨胀 背景变大 内容变小
Imgproc.dilate(vertical, vertical, verticalStructure , new Point(-1, -1), 1);
- 合并得到的横线和竖线图Core.add(horizontal, vertical, result);
- 接着常规法1:操作 面积、轮廓顶点数过滤、坐标过滤
//轮廓提起
Imgproc.findContours(result, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); i++) {
//轮廓
Rect rect1 = Imgproc.boundingRect(contours.get(i));
//面积过滤
if(Imgproc.contourArea(contours.get(i))<100){
continue;
}
//多边形包围轮廓 后面可以判断顶点个数过滤
//MatOfPoint2f curve = new MatOfPoint2f(contours.get(i).toArray());
//MatOfPoint2f approxCurve = new MatOfPoint2f();
//Imgproc.approxPolyDP(curve, approxCurve, 0.025 * Imgproc.arcLength(curve, true), true);
//得到顶点数
//approxCurve.toArray().length
//
}
- 接着常规法2:和前面文章提到的类似,得到交叉坐标点处理Core.bitwise_and(horizontal, vertical, addMat);
- 1.交叉点像素值是255的或者>0,得到所有的坐标点
- 2.x坐标一直 竖线坐标,y坐标一直 横线过滤,误差大小过滤
- 3.横线和竖线进行排序
- 4.计算交叉点进行切图
- 5.ocr进行文字识别
转载自:https://juejin.cn/post/7358458856038678555