#include<opencv2/opencv.hpp> #include<iostream> #include<cmath> using namespace std; using namespace cv; const char input[] = "Input image"; const char output[] = "Output image"; void fileCutLine(int, void*);//对图片边缘切取 void rotateImage(int,void*);//对于图片进行旋转矫正 Mat src, dst,rotateSrc; int main(void) { src = imread("..\\cutLineTest.jpg"); rotateSrc = imread("..\\rotateTestImage.jpg"); if (src.empty()||rotateSrc.empty()) { cout << "Loading image failed!" << endl; return -1; } pyrDown(rotateSrc, rotateSrc); namedWindow(input, WINDOW_AUTOSIZE); namedWindow(output, WINDOW_AUTOSIZE); int thresh = 134; //createTrackbar("Control threshold", output, &thresh, 255, fileCutLine); //fileCutLine(thresh, 0); createTrackbar("Rotate fix", output, &thresh, 255, rotateImage); rotateImage(thresh, 0); //imshow(input, src); imshow(input, rotateSrc); waitKey(0); return 0; } void fileCutLine(int thresh, void*) { Mat gray; Mat border; Mat kernel = Mat(Size(3, 3), CV_8UC1); cvtColor(src, gray, COLOR_BGR2GRAY); GaussianBlur(gray, gray, Size(7, 7), 0); //高斯模糊降噪 Canny(gray, border, thresh, 2 * thresh); //通过开操作将黑色边缘上的水映文字去掉 morphologyEx(border, border, MORPH_OPEN, kernel); vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(border, contours,hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE,Point(0,0)); Rect mask;//最后获得的正确范围的遮罩 //Mat temp = Mat::zeros(src.size(), CV_8UC3); //临时图像承载,用于观察边框 for (int i = 0; i < contours.size(); i++){ RotatedRect rect = minAreaRect(contours[i]); Point2f corner[4]; //设置图片尺度条件,进行边缘矩形筛选 if ((rect.size.width > src.cols*0.75) && rect.size.height>src.rows*0.75) { rect.points(corner); //cout << "************************" << endl; line(border, corner[0], corner[1], Scalar(0, 0, 255),2); line(border, corner[1], corner[2], Scalar(0, 0, 255),2); line(border, corner[3], corner[2], Scalar(0, 0, 255),2); line(border, corner[3], corner[0], Scalar(0, 0, 255),2); mask = rect.boundingRect();//返回包含旋转矩形的矩形 } } cout << mask.width << ' ' << mask.height << endl; cout << src.cols << ' ' << src.rows << endl; //imshow("temp", temp); dst = src(mask);//比较好用 imshow(output, border); if (!dst.empty()) { imshow("Result", dst); } } //如果图片是倾斜 void rotateImage(int thresh,void*) { //Mat gray; Mat border; Mat kernel = Mat(Size(3, 3), CV_8UC1); //cvtColor(rotateSrc, gray, COLOR_BGR2GRAY); Canny(rotateSrc, border, thresh, 2 * thresh); //通过开操作将黑色边缘上的水映文字去掉 //morphologyEx(border, border, MORPH_OPEN, kernel); vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(border, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0)); double angle = 0;//需要记录角度 Point2f center=Point2f(rotateSrc.rows/2,rotateSrc.cols/2); Size fixSize; Rect mask; Mat temp = Mat(rotateSrc.size(),CV_8UC3); for (int i = 0; i < contours.size(); i++){ RotatedRect rect = minAreaRect(contours[i]); //center = rect.center; Point2f corner[4]; rect.points(corner); for (int j = 0; j < 4; j++) { line(temp, corner[j], corner[(j + 1) % 4], Scalar(255,255,255), 2); } if (rect.angle != 0) { angle = rect.angle; cout << "Angle:" << angle << endl; } } Mat martix = getRotationMatrix2D(center, angle, 1);//得到仿射矩阵 warpAffine(rotateSrc, dst, martix, rotateSrc.size()); imshow("result", dst); imshow(output,border); }
在调整阈值时加了traceBar,调的时候方便一些。
结果如下(图是百度上随便找的):