2014-04-09 66 views
1

我正在编写一个移动应用程序来绘制表格数据的图形表示(图表/图表)。用户正在拍摄统计表格的图像。我必须检测表格并裁剪所有单元格以便使用tessaract引擎执行OCR。 是否有适当的方法来识别图像中的表格并循环遍历单元格并将其保存到数组中?使用opencv读取表格(图片)单元格数据单元格

到目前为止,我已经能够使用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); 

有没有一种方法来遍历细胞,并在订单作物呢?

回答

2

好了,简单的方法在这里找到细胞:

你会发现在过滤图像的轮廓,并建立一个边框圆他们。

此外,您可以使用特定轮廓的大小和/或颜色信息来消除太小或太大的轮廓。

下面是一些代码:

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); 

enter image description here

分析内容和文字识别是一个相当复杂的任务,而据我所知在OpenCV中没有默认的方法来执行这一点,所以它需要一些研究明显。

+0

非常感谢答复。我会尽快尝试。我正在使用tesseract引擎做ocr模块。所以需要裁剪每个单元格,然后将其传递给tesseract。无论如何,我可以通过订单裁剪轮廓吗? – ChathuraSam

+0

@ user3411228您应该使用某种排序方式,例如先按Y轴排序,然后按X轴排序,同时考虑到单元格的“浮动”边框。例如:http://codepad.org/GBJBG5Iv – degot

+0

再次感谢。 我试过你的第一个答案。你知道以下错误的原因吗? '错误C4996:'sprintf':此函数或变量可能不安全。考虑使用sprintf_s代替。要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS。' – ChathuraSam