#include<opencv2/opencv.hpp>
#include<iostream>
#include<algorithm>
using namespace cv;
using namespace std;
bool sortrectx(Rect& rect1, Rect& rect2);
bool sortrecty(Rect& rect1, Rect& rect2);
Point2f* sortpoint(Point2f* arr, int lenth);
void getList(Mat img);
int main()
{
Mat src = imread("E:\\dataset\\dataset\\202\\chart.png");
if (src.empty())
{
cout << "fail to load the picture" << endl;
return -1;
}
Mat dst;
resize(src, dst, Size(0, 0), 0.3, 0.4, INTER_AREA);
Mat srclone = dst.clone();
//namedWindow("dst", WINDOW_NORMAL);
//imshow("dst", dst);
//namedWindow("表格图", WINDOW_AUTOSIZE);
//imshow("表格图", src);
Mat gray;
cvtColor(srclone, gray, COLOR_BGR2GRAY);
//namedWindow("灰度图", WINDOW_AUTOSIZE);
//imshow("灰度图",gray);
Mat yuzhi;
adaptiveThreshold(~gray, yuzhi, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
//namedWindow("阈值图", WINDOW_AUTOSIZE);
//imshow("阈值图", yuzhi);
Mat structure = getStructuringElement(MORPH_RECT, Size(2, 2));
//erode(yuzhi, yuzhi, structure, Point(-1, -1));
//dilate(yuzhi, yuzhi, structure, Point(-1, -1));
//imshow("dilate", yuzhi);
vector<Vec4i>hierarchy;
vector<vector<Point>>contours;
findContours(yuzhi, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
//cout << contours.size();
vector<vector<Point>>contours_poly(contours.size());
int indexmax = 0;
double areamax = 0;
for (int i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area < 20)
continue;
//drawContours(srclone, contours, i, Scalar(0, 255, 0),1,8);
approxPolyDP(contours[i], contours_poly[i], 10, true);//输出是多边形的顶点
if (area > areamax)
{
areamax = area;
indexmax = i;
}
}
for (size_t j = 0; j < contours_poly[indexmax].size(); j++)
{
cout << contours_poly[indexmax][j] << endl;
}
drawContours(srclone, contours, indexmax, Scalar(0, 255, 0), 1, 8);
//namedWindow("lunkuo", WINDOW_NORMAL);
//imshow("lunkuo", srclone);
//Rect bondrect;
//bondrect = boundingRect(Mat(contours_poly[indexmax]));
//Mat roi = dst(bondrect).clone();
//namedWindow("roi", WINDOW_NORMAL);
//imshow("roi", roi);
Mat polypic = Mat(dst.size(), CV_8UC3, Scalar(0, 0, 0));
drawContours(polypic, contours, indexmax, Scalar(0, 255, 0), 1, 8);
//namedWindow("polypic", WINDOW_NORMAL);
//imshow("polypic", polypic);
Mat outpic = Mat(Size(1800, 1200), dst.type(), Scalar(255, 255, 255));
Point2f dstpoint[4];
dstpoint[0] = Point2f(100, 100);
dstpoint[1] = Point2f(100, 1100);
dstpoint[2] = Point2f(1700, 100);
dstpoint[3] = Point2f(1700, 1100);
Point2f arr[4] = { contours_poly[indexmax][0],contours_poly[indexmax][1] ,contours_poly[indexmax][2] ,contours_poly[indexmax][3] };
Point2f* srcpoint = sortpoint(arr, 3);
for (size_t j = 0; j < 4; j++)
{
cout << srcpoint[j] << endl;
}
Mat transmat = getPerspectiveTransform(srcpoint, dstpoint);
warpPerspective(dst, outpic, transmat, outpic.size(), INTER_LANCZOS4, 0, Scalar(255, 255, 255));
//namedWindow("outpic", WINDOW_AUTOSIZE);
//imshow("outpic", outpic);
//imwrite("E:\\图片\\outpic.jpg", outpic);
getList(outpic);
waitKey();
return 0;
}
Point2f* sortpoint(Point2f* arr, int lenth)
{
Point2f t;
for (int i = 0; i < lenth; i++)
for (int j = 0; j < lenth - 1 - i; j++)
{
if (arr[j].x > arr[j + 1].x)
{
t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
if (arr[0].y > arr[1].y)
{
t = arr[0];
arr[0] = arr[1];
arr[1] = t;
}
if (arr[2].y > arr[3].y)
{
t = arr[2];
arr[2] = arr[3];
arr[3] = t;
}
return arr;
}
void getList(Mat img)
{
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
Mat yuzhi;
adaptiveThreshold(~gray, yuzhi, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
//namedWindow("阈值图", WINDOW_AUTOSIZE);
//imshow("阈值图", yuzhi);
Mat horizontal = yuzhi.clone();
Mat vertical = yuzhi.clone();
int scale = 20;
int horizontalsize = horizontal.cols / scale;
int verticalsize = vertical.rows / scale;
Mat horizontalstructure = getStructuringElement(MORPH_RECT, Size(horizontalsize, 1));
erode(horizontal, horizontal, horizontalstructure, Point(-1, -1));
dilate(horizontal, horizontal, horizontalstructure, Point(-1, -1));
dilate(horizontal, horizontal, horizontalstructure, Point(-1, -1));
//namedWindow("横线", WINDOW_AUTOSIZE);
//imshow("横线", horizontal);
Mat verticalstructure = getStructuringElement(MORPH_RECT, Size(1, verticalsize));
erode(vertical, vertical, verticalstructure, Point(-1, -1));
dilate(vertical, vertical, verticalstructure, Point(-1, -1));
//namedWindow("竖线", WINDOW_AUTOSIZE);
//imshow("竖线", vertical);
Mat joint;
bitwise_and(horizontal, vertical, joint);
//namedWindow("交点", WINDOW_AUTOSIZE);
//imshow("交点", joint);
Mat mask = horizontal + vertical;
//namedWindow("结果", WINDOW_AUTOSIZE);
//imshow("结果", mask);
vector<Vec4i>hierarchy;
vector<vector<Point>>contours;
findContours(mask, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
//cout << contours.size() << endl;
vector<vector<Point>>contours_poly(contours.size());
vector<Rect>boundRect;
vector<Mat>Rois;
vector<Rect>rects;
for (int i = 0; i < contours.size(); i++)
{
double area = contourArea(contours[i]);
if (area < 10000 || area>300000)
continue;
approxPolyDP(contours[i], contours_poly[i], 3, true);
boundRect.push_back(boundingRect(Mat(contours_poly[i])));
}
sort(boundRect.begin(), boundRect.end(), sortrecty);
//sort(boundRect.begin(), boundRect.end(), sortrecty);
vector<Rect> ::iterator iter = boundRect.begin();
for (int i = 0; i < boundRect.size()-6; i++)
{
if (i % 7 == 0)
{
sort(iter+i, iter+7+i, sortrectx);//注意如果表格不是我这样的,这块代码适当修改即可
}
}
for (int i = 0; i < boundRect.size(); i++)
{
Rois.push_back(img(boundRect[i]).clone());
}
//cout << boundRect.size() << endl;
cout << Rois.size();
vector<Mat>image(Rois.size());
for (int i = 0; i < Rois.size(); i++)
{
cvtColor(Rois[i], Rois[i], COLOR_BGR2GRAY);
char name[30];
sprintf_s(name, "rois%d", i);
//namedWindow(name, WINDOW_AUTOSIZE);
//imshow(name, Rois[i]);
string Img_Name = "E:\\dataset\\dataset\\203\\" + to_string(10+i)+ "." + to_string(257)+" .jpg";
imwrite(Img_Name, Rois[i]);
}
}
bool sortrectx(Rect& rect1, Rect& rect2)
{
return rect1.tl().x <= rect2.tl().x;
}
bool sortrecty(Rect& rect1, Rect& rect2)
{
return rect1.tl().y <= rect2.tl().y;
}
//代码不懂得地方,或者有误的欢迎大家讨论
效果
就展示这几张图,后面的就不做展示了