1.通过霍夫线矫正土图片
网络异常,图片无法展示
|
public static void getCorrect1(Mat image) { Mat clone=image.clone(); Mat src=image.clone(); int width = image.width(); int height = image.height(); int pointCount = width * height; Mat points=image.reshape(3, pointCount); points.convertTo(points, CvType.CV_32F); Imgproc.GaussianBlur(clone, clone, new Size(3, 3), 0, 0); HighGui.imshow("GaussianBlur", clone); Imgproc.cvtColor(clone, clone,Imgproc.COLOR_BGR2GRAY); HighGui.imshow("GRY", clone); //一般来说,高阈值maxVal推荐是低阈值minVal的2~3倍 int lowThresh=20; //边缘检测 Imgproc.Canny(clone, clone,lowThresh, lowThresh*3,3); HighGui.imshow("Canny", clone); Mat storage = new Mat(); /** * HoughLines(Mat image, Mat lines, double rho, double theta, int threshold, double srn, double stn, double min_theta, double max_theta) * image 原图 * lines 霍夫线变换检测到线条的输出矢量,由(ρ,θ)表示 * rho 以像素为单位的距离精度(直线搜索时的进步尺寸的单位半径) * theta 以弧度为单位的角度精度(直线搜索时的进步尺寸的角度单位) * threshold 累加平面的阈值参数(直线被识别时它在累加平面中必须达到的值) * srn 对于多尺度霍夫变换,这是第三个参数进步尺寸的除数距离。 * 粗略累加器进步尺寸直接是rho,精确的累加器进步尺寸为rho/srn * min_theta 检测到的直线的最小角度 * max_theta 测到的直线的最大角度 */ double sum = 0; double angle=0; Imgproc.HoughLines(clone, storage, 1, Math.PI/ 180.0, 200, 0, 0); for (int x = 0; x < storage.rows(); x++) { double[] vec = storage.get(x, 0); double rho = vec[0]; double theta = vec[1]; Point pt1 = new Point(); Point pt2 = new Point(); double a = Math.cos(theta); double b = Math.sin(theta); double x0 = a * rho; double y0 = b * rho; pt1.x = Math.round(x0 + 1000 * (-b)); pt1.y = Math.round(y0 + 1000 * (a)); pt2.x = Math.round(x0 - 1000 * (-b)); pt2.y = Math.round(y0 - 1000 * (a)); sum += theta; Imgproc.line(clone, pt1, pt2, new Scalar(255, 255, 255, 255), 1, Imgproc.LINE_4, 0); } HighGui.imshow("houghLines", clone); double average = sum / storage.rows(); //对所有角度求平均,这样做旋转效果会更好 angle = average/ Math.PI * 180 - 90; System.out.println("average:"+angle); Point center=new Point(); center.x=image.cols()/2; center.y=image.rows()/2; // 得到旋转矩阵算子 Mat matrix = Imgproc.getRotationMatrix2D(center, angle, 1); Imgproc.warpAffine(src, src, matrix,src.size(), 1, 0, new Scalar(0, 0, 0)); HighGui.imshow("rotation", src); } 复制代码
2.通过轮廓检测矫正土图片
网络异常,图片无法展示
|
public static Mat getCorrect2(Mat image) { Mat clone=image.clone(); Mat src=image.clone(); int width = image.width(); int height = image.height(); int pointCount = width * height; Mat points=image.reshape(3, pointCount); points.convertTo(points, CvType.CV_32F); Imgproc.GaussianBlur(clone, clone, new Size(3, 3), 0, 0); HighGui.imshow("GaussianBlur", clone); Imgproc.cvtColor(clone, clone,Imgproc.COLOR_BGR2GRAY); HighGui.imshow("GRY", clone); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); // 寻找轮廓 Imgproc.findContours(clone, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE, new Point(0, 0)); // 找出匹配到的最大轮廓 double area = Imgproc.boundingRect(contours.get(0)).area(); int index = 0; // 找出匹配到的最大轮廓 for (int i = 0; i < contours.size(); i++) { double tempArea = Imgproc.boundingRect(contours.get(i)).area(); if (tempArea > area) { area = tempArea; index = i; } } MatOfPoint2f matOfPoint2f = new MatOfPoint2f(contours.get(index).toArray()); RotatedRect rect = Imgproc.minAreaRect(matOfPoint2f); // 获取矩形的四个顶点 Point[] rectpoint = new Point[4]; rect.points(rectpoint); double line1 = Math.sqrt((rectpoint[1].y - rectpoint[0].y)*(rectpoint[1].y - rectpoint[0].y) + (rectpoint[1].x - rectpoint[0].x)*(rectpoint[1].x - rectpoint[0].x)); double line2 = Math.sqrt((rectpoint[3].y - rectpoint[0].y)*(rectpoint[3].y - rectpoint[0].y) + (rectpoint[3].x - rectpoint[0].x)*(rectpoint[3].x - rectpoint[0].x)); double angle = rect.angle; if (line1 > line2) { angle = 90 + angle; } Point center = rect.center; Mat CorrectImg = new Mat(clone.size(), clone.type()); clone.copyTo(CorrectImg); // 得到旋转矩阵算子 Mat matrix = Imgproc.getRotationMatrix2D(center, angle, 0.8); Imgproc.warpAffine(src, src, matrix, CorrectImg.size(), 1, 0, new Scalar(0, 0, 0)); HighGui.imshow("rotation", src); return src; }