我正在编写一个移动应用程序来绘制表格数据的图形表示(图形/图表)。用户正在拍摄统计表的图像。我必须检测表格并裁剪所有单元格才能使用 tessaract 引擎执行 OCR。 是否有正确的方法来识别图像中的表格并循环单元格并将它们保存到数组中?
到目前为止,我已经能够使用 opencv C++ 如下清理图像。
代码:
const char* filename = argc >= 2 ? argv[1] : "test.jpg";
Mat src = imread(filename);
if(src.empty())
{
//help();
cout << "can not open " << filename << endl;
return -1;
}
Mat dst, cdst, img2;
GaussianBlur(src,dst,Size(5,5),0);
cvtColor(dst, dst, CV_RGB2GRAY);
adaptiveThreshold(dst, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY, 31, 15);
namedWindow("dst",WINDOW_NORMAL);
imshow("dst", dst);
有没有办法循环遍历单元格并按顺序裁剪它们?
最佳答案
好的,在这里查找单元格的简单方法:
您在过滤后的图像中找到轮廓并在它们周围构建边界框。
您还可以使用特定轮廓的大小和/或颜色信息来消除太小或太大的轮廓。
这是一些代码:
Mat src = imread("g.png");
cvtColor(src, src, CV_BGR2GRAY);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny( src, src, 100, 200, 3 );
imshow("g",src);
findContours( src, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
char text[200] = "";
CvFont font = cvFont(2,2);
for( int i = 0; i< contours.size(); i++ )
{
drawContours( drawing, contours, i, CV_RGB(255,0,0), 2, 8, hierarchy, 0, Point() );
cv::Rect brect = cv::boundingRect(contours[i]);
if (brect.area() < 1000)
continue;
sprintf(text,"S = %d", brect.area());
putText(drawing, text, cvPoint(brect.x+20, brect.y+20), 1, 1, CV_RGB(0,255,0));
rectangle(drawing, brect, CV_RGB(0,0,255), 3);
}
imshow( "Contours", drawing);
分析内容和文本识别是一项相当复杂的任务,而且我知道 OpenCV 中没有默认方法来执行此操作,因此显然需要一些研究。
关于c++ - 使用opencv逐个单元读取表格(图像)的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22961635/