#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,調的時候方便一些。
結果如下(圖是百度上隨便找的):