#include<iostream>
#include<opencv.hpp>
using namespace cv;
using namespace std;
void chao_thinimage(Mat &srcimage)//单通道、二值化后的图像
{
vector<Point> deletelist1;
int Zhangmude[9];
int nl = srcimage.rows;
int nc = srcimage.cols;
while (true)
{
for (int j = 1; j < (nl - 1); j++)
{
uchar* data_last = srcimage.ptr<uchar>(j - 1);
uchar* data = srcimage.ptr<uchar>(j);
uchar* data_next = srcimage.ptr<uchar>(j + 1);
for (int i = 1; i < (nc - 1); i++)
{
if (data[i] == 255)
{
Zhangmude[0] = 1;
if (data_last[i] == 255) Zhangmude[1] = 1;
else Zhangmude[1] = 0;
if (data_last[i + 1] == 255) Zhangmude[2] = 1;
else Zhangmude[2] = 0;
if (data[i + 1] == 255) Zhangmude[3] = 1;
else Zhangmude[3] = 0;
if (data_next[i + 1] == 255) Zhangmude[4] = 1;
else Zhangmude[4] = 0;
if (data_next[i] == 255) Zhangmude[5] = 1;
else Zhangmude[5] = 0;
if (data_next[i - 1] == 255) Zhangmude[6] = 1;
else Zhangmude[6] = 0;
if (data[i - 1] == 255) Zhangmude[7] = 1;
else Zhangmude[7] = 0;
if (data_last[i - 1] == 255) Zhangmude[8] = 1;
else Zhangmude[8] = 0;
int whitepointtotal = 0;
for (int k = 1; k < 9; k++)
{
whitepointtotal = whitepointtotal + Zhangmude[k];
}
if ((whitepointtotal >= 2) && (whitepointtotal <= 6))
{
int ap = 0;
if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;
if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;
if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;
if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;
if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;
if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;
if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;
if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;
if (ap == 1)
{
if ((Zhangmude[1] * Zhangmude[7] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[5] * Zhangmude[7] == 0))
{
deletelist1.push_back(Point(i, j));
}
}
}
}
}
}
if (deletelist1.size() == 0) break;
for (size_t i = 0; i < deletelist1.size(); i++)
{
Point tem;
tem = deletelist1[i];
uchar* data = srcimage.ptr<uchar>(tem.y);
data[tem.x] = 0;
}
deletelist1.clear();
for (int j = 1; j < (nl - 1); j++)
{
uchar* data_last = srcimage.ptr<uchar>(j - 1);
uchar* data = srcimage.ptr<uchar>(j);
uchar* data_next = srcimage.ptr<uchar>(j + 1);
for (int i = 1; i < (nc - 1); i++)
{
if (data[i] == 255)
{
Zhangmude[0] = 1;
if (data_last[i] == 255) Zhangmude[1] = 1;
else Zhangmude[1] = 0;
if (data_last[i + 1] == 255) Zhangmude[2] = 1;
else Zhangmude[2] = 0;
if (data[i + 1] == 255) Zhangmude[3] = 1;
else Zhangmude[3] = 0;
if (data_next[i + 1] == 255) Zhangmude[4] = 1;
else Zhangmude[4] = 0;
if (data_next[i] == 255) Zhangmude[5] = 1;
else Zhangmude[5] = 0;
if (data_next[i - 1] == 255) Zhangmude[6] = 1;
else Zhangmude[6] = 0;
if (data[i - 1] == 255) Zhangmude[7] = 1;
else Zhangmude[7] = 0;
if (data_last[i - 1] == 255) Zhangmude[8] = 1;
else Zhangmude[8] = 0;
int whitepointtotal = 0;
for (int k = 1; k < 9; k++)
{
whitepointtotal = whitepointtotal + Zhangmude[k];
}
if ((whitepointtotal >= 2) && (whitepointtotal <= 6))
{
int ap = 0;
if ((Zhangmude[1] == 0) && (Zhangmude[2] == 1)) ap++;
if ((Zhangmude[2] == 0) && (Zhangmude[3] == 1)) ap++;
if ((Zhangmude[3] == 0) && (Zhangmude[4] == 1)) ap++;
if ((Zhangmude[4] == 0) && (Zhangmude[5] == 1)) ap++;
if ((Zhangmude[5] == 0) && (Zhangmude[6] == 1)) ap++;
if ((Zhangmude[6] == 0) && (Zhangmude[7] == 1)) ap++;
if ((Zhangmude[7] == 0) && (Zhangmude[8] == 1)) ap++;
if ((Zhangmude[8] == 0) && (Zhangmude[1] == 1)) ap++;
if (ap == 1)
{
if ((Zhangmude[1] * Zhangmude[3] * Zhangmude[5] == 0) && (Zhangmude[3] * Zhangmude[1] * Zhangmude[7] == 0))
{
deletelist1.push_back(Point(i, j));
}
}
}
}
}
}
if (deletelist1.size() == 0) break;
for (size_t i = 0; i < deletelist1.size(); i++)
{
Point tem;
tem = deletelist1[i];
uchar* data = srcimage.ptr<uchar>(tem.y);
data[tem.x] = 0;
}
deletelist1.clear();
}
}
//subfunction
bool cmpy_y(cv::Point const& a, cv::Point const& b)
{
return a.y < b.y;
}
bool cmpy_x(cv::Point const& a, cv::Point const& b)
{
return a.x < b.x;
}
int main()
{
cout << "hello world" << endl;
Mat srcImg = imread("E:\\fengce\\TEST\\9.tif");
Mat dstImg;
cvtColor(srcImg,dstImg,CV_BGR2GRAY);
Mat bw;
adaptiveThreshold(~dstImg, bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
// chao_thinimage(bw);
imshow("bw", bw);
Mat horizontal = bw.clone();
Mat vertical = bw.clone();
int scale = 20; //这个值越大,检测到的直线越多
int horizontalsize = horizontal.cols / scale;
// 为了获取横向的表格线,设置腐蚀和膨胀的操作区域为一个比较大的横向直条
Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize, 1));
// 先腐蚀再膨胀
erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
//imshow("horizontal", horizontal);
int verticalsize = vertical.rows / scale;
Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1, verticalsize));
erode(vertical, vertical, verticalStructure, Point(-1, -1));
dilate(vertical, vertical, verticalStructure, Point(-1, -1));
//imshow("vertical", vertical);
Mat mask = horizontal + vertical;
imshow("mask", mask);
chao_thinimage(horizontal);
chao_thinimage(vertical);
Mat joints;
bitwise_and(horizontal, vertical, joints);
vector<Point> temp;
vector<Point> endtemp;
Point start;
//寻找左上角点
for (int i = 0; i < joints.rows; i++)
{
uchar *data = joints.ptr<uchar>(i);
for (int j = 0; j < joints.cols; j++)
{
if (data[j] == 255 && data[j - 1] == 0)
{
start.x = j;
start.y = i;
temp.push_back(start);
endtemp.push_back(start);
}
}
}
sort(temp.begin(), temp.end(), cmpy_x);
sort(endtemp.begin(),endtemp.end(), cmpy_y);
for (int j = 0; j < temp.size(); j++)
{
cout << temp[j]<< endl;
}
cout << "y=" << endl;
for (int j = 0; j < endtemp.size(); j++)
{
cout << endtemp[j] << endl;
}
int x0 = temp[0].x+2;
int y0 = temp[0].y+2;
int width = temp[temp.size() - 1].x - temp[0].x-2;
int height = endtemp[endtemp.size() - 1].y - endtemp[0].y-2;
if (width <= srcImg.cols - x0 && height <= srcImg.rows - y0)
{
Mat ROI(srcImg, Rect(x0, y0, width, height));
imshow("ROI", ROI);
}
else
{
cout << "获取失败" << endl;
}
//寻找右下角的点
//imwrite("joints.tif",joints);
imshow("joints", joints);
imshow("src", srcImg);
//cout << start << endl;
waitKey(0);
return 0;
}
欢迎交流