这是我的第一个openCV程序,如果我对某些基本的计算机视觉概念一无所知,那就宽恕吧.
更新:由于sturkmen的回答,请查看底部的新代码/新问题
我正在努力将一大堆图像"数字化",就像附加的图像一样,作为一个项目.所有图像都来自同一来源.最终目标是将提取的文本块传递给tesseract,即OCR库.
(源代码在底部) 我将解释我当前的方法,然后陈述我的问题.
我目前的做法如下:
应用反二进制阈值
扩张图像并找到轮廓
boundingRect
从每个轮廓创建一个,然后过滤最小和最大尺寸
这工作正常
我期望的最终结果是boundingRect
每列周围有一个.因此,对于提供的图片,其中有七个.
因此,问题在于图像中的列表"迷你部分"未被可靠地拾取(最好的例子是最右边的列中没有boundingRect
围绕它的那个).
我可以想到两个可能的解决方案(以便不是一个开放式/意见类型的问题),但如果你知道一个更好的解决方案,请分享它!
1)组合boundingRect
垂直邻居的s来捕获列.包含可能的边缘情况故障.
2)找到一种不同的方法来处理图像,然后再找到轮廓.根据我的研究,运行长度平滑算法看起来很有前景?
所以我的问题是,哪种方法最好?我忽略了一个更好的解决方案吗?我在这个部门缺乏经验,所以没有任何建议太小.
谢谢阅读!
#include "opencv2/core.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include#include #include #include using namespace cv; using namespace std; int main(int argc, char* argv[]) { Mat image = imread(path_to_file); Mat gray; cvtColor(image, gray, COLOR_BGR2GRAY); Mat fin; double thresh = threshold(gray, fin, 160, 255, THRESH_BINARY_INV); //size impacts dilation Mat kernel = getStructuringElement(MORPH_CROSS, Size(2, 4)); Mat dilated; dilate(fin, dilated, kernel, Point(-1,-1), 6); imwrite("testbw.png",dilated); Mat hierarchy; vector >contours; findContours(dilated, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE); //potentially sort by x for (const auto& c : contours) { // x y //columns 850 x 5400 Rect r = boundingRect(c); if (r.height > 3000 || r.width > 875) continue; if (r.height < 100 || r.width < 500) continue; rectangle(image, r, Scalar(255, 0, 255), 2); //made thicker } imwrite("test.png", image); waitKey(0); return 0;
}
原始图片:
更新的代码
int main(int argc, char* argv[]) { Mat image = imread(path_to_file); Mat gray; cvtColor(image, gray, COLOR_BGR2GRAY); Mat fin; double thresh = threshold(gray, fin, 160, 255, THRESH_BINARY_INV); Mat kernel = getStructuringElement(MORPH_CROSS, Size(2, 4)); Mat dilated; dilate(fin, dilated, kernel, Point(-1,-1), 6); vectorhierarchy; vector >contours; findContours(dilated, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE); vector rects; Rect big_rect = Rect(image.cols/2,image.rows/2,1,1); for (const auto& c : contours) { // x y //columns 850 x 5400 Rect r = boundingRect(c); if (r.height > 5500 || r.width > 875) continue; if (r.height < 300 || r.width < 500) continue; big_rect = big_rect | r; // here we will find bounding box of all Rects rects.push_back( r ); // stores rects } for ( size_t i = 0; i < rects.size(); i++ ) { // sets y and height of all rects //cout << rects[i].x << endl; rects[i].y = big_rect.y; rects[i].height = big_rect.height; } //groupRectangles(rects, 1); DIDN'T WORK for ( size_t i = 0; i < rects.size(); i++ ) { rectangle(image, rects[i], Scalar(255, 0, 255), 2); } imshow("test", image);
新结果:
新问题:boundingRect
每列周围有很多s(你可能无法通过查看图片来判断).这是一个问题,因为我想制作每列的子图像,例如Mat ROI = image(rects[i])
,它将比所需的7个图像渲染得多.
新问题:如何将每列的多个矩形合并为一个?我见过openCV groupRectangles
,但它无法正常工作.