private void Correct(Mat src) { Mat[] mat_list = new Mat[9]; int img_w = src.cols(); int img_h = src.rows(); Mat gary = new Mat(); Mat edges = new Mat(); Mat hierarchy =new Mat(); Mat rotated_image = new Mat(); Mat crop_image = new Mat(); List<MatOfPoint> contours = new ArrayList<>(); Imgproc.cvtColor(src, gary, Imgproc.COLOR_RGB2GRAY); Imgproc.threshold(gary, edges, 70,255,Imgproc.THRESH_BINARY_INV); HighGui.imshow("edges", edges); HighGui.waitKey(0); Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
List<MatOfPoint> squares = new ArrayList<>(); List<MatOfPoint> hulls = new ArrayList<>(); MatOfInt hull = new MatOfInt(); MatOfPoint2f approx = new MatOfPoint2f(); approx.convertTo(approx, CvType.CV_32F);
for (MatOfPoint contour: contours) { Imgproc.convexHull(contour, hull);
Point[] contourPoints = contour.toArray(); int[] indices = hull.toArray(); List<Point> newPoints = new ArrayList<>(); for (int index : indices) { newPoints.add(contourPoints[index]); } MatOfPoint2f contourHull = new MatOfPoint2f(); contourHull.fromList(newPoints);
Imgproc.approxPolyDP(contourHull, approx, Imgproc.arcLength(contourHull, true)*0.02, true);
MatOfPoint approxf1 = new MatOfPoint(); approx.convertTo(approxf1, CvType.CV_32S); System.out.println("---------------------------------------"); System.out.println(approx.rows()); System.out.println(Math.abs(Imgproc.contourArea(approx))); System.out.println(Imgproc.isContourConvex(approxf1)); System.out.println("---------------------------------------"); if (approx.rows() == 4 && Math.abs(Imgproc.contourArea(approx)) > 2000 && Imgproc.isContourConvex(approxf1)) { double maxCosine = 0; for (int j = 2; j < 5; j++) { double cosine = Math.abs(getAngle(approxf1.toArray()[j%4], approxf1.toArray()[j-2], approxf1.toArray()[j-1])); maxCosine = Math.max(maxCosine, cosine); System.out.println("maxCosine" + maxCosine); } if (maxCosine < 0.3) { MatOfPoint tmp = new MatOfPoint(); contourHull.convertTo(tmp, CvType.CV_32S); squares.add(approxf1); hulls.add(tmp); } } } Imgproc.polylines(src, contours, true, new Scalar(255, 0, 0));
HighGui.imshow("src", src); HighGui.waitKey(0); int index = findLargestSquare(squares); if(index == -1) { System.out.println("外接矩阵最大四边形没找到"); return mat_list; } MatOfPoint largest_square = squares.get(index); if (largest_square.rows() == 0 || largest_square.cols() == 0) return mat_list;
MatOfPoint contourHull1 = hulls.get(index); MatOfPoint2f tmp = new MatOfPoint2f(); contourHull1.convertTo(tmp, CvType.CV_32F); Imgproc.approxPolyDP(tmp, approx, 3, true); List<Point> newPointList = new ArrayList<>(); double maxL = Imgproc.arcLength(approx, true) * 0.02;
for (Point p : approx.toArray()) { if (!(getSpacePointToPoint(p, largest_square.toList().get(0)) > maxL && getSpacePointToPoint(p, largest_square.toList().get(1)) > maxL && getSpacePointToPoint(p, largest_square.toList().get(2)) > maxL && getSpacePointToPoint(p, largest_square.toList().get(3)) > maxL)) { newPointList.add(p); } }
List<double[]> lines = new ArrayList<>(); for (int i = 0; i < newPointList.size(); i++) { Point p1 = newPointList.get(i); Point p2 = newPointList.get((i+1) % newPointList.size()); if (getSpacePointToPoint(p1, p2) > 2 * maxL) { lines.add(new double[]{p1.x, p1.y, p2.x, p2.y}); } }
List<Point> corners = new ArrayList<>(); for (int i = 0; i < lines.size(); i++) { Point corner = computeIntersect(lines.get(i),lines.get((i+1) % lines.size())); corners.add(corner); }
sortCorners(corners);
Point p0 = corners.get(0); Point p1 = corners.get(1); Point p2 = corners.get(2); Point p3 = corners.get(3); Point[] pointArr = new Point[4]; pointArr[0] = p0; pointArr[1] = p1; pointArr[2] = p2; pointArr[3] = p3; MatOfPoint2f matOfPoint2f = new MatOfPoint2f(pointArr); System.out.println(Imgproc.minAreaRect(matOfPoint2f)); double space0 = getSpacePointToPoint(p0, p1); double space1 = getSpacePointToPoint(p1, p2); double space2 = getSpacePointToPoint(p2, p3); double space3 = getSpacePointToPoint(p3, p0);
double imgWidth = space1 > space3 ? space1 : space3; double imgHeight = space0 > space2 ? space0 : space2;
System.out.println( space0+"-"+ space1+"-"+ space2+"-"+ space3); if (imgWidth < imgHeight) { double temp = imgWidth; imgWidth = imgHeight; imgHeight = temp; Point tempPoint = p0.clone(); p0 = p3.clone(); p3 = p2.clone(); p2 = p1.clone(); p1 = tempPoint.clone(); }
System.out.println(p0 + "-" + p2); Imgproc.putText(src, "P0", p0, Imgproc.FONT_HERSHEY_COMPLEX, 0.8, new Scalar(0,0,0)); Imgproc.putText(src, "P1", p1, Imgproc.FONT_HERSHEY_COMPLEX, 0.8, new Scalar(0,0,0)); Imgproc.putText(src, "P2", p2, Imgproc.FONT_HERSHEY_COMPLEX, 0.8, new Scalar(0,0,0)); Imgproc.putText(src, "P3", p3, Imgproc.FONT_HERSHEY_COMPLEX, 0.8, new Scalar(0,0,0)); HighGui.imshow("src image", src); HighGui.waitKey(0);
Mat quad = Mat.zeros((int)img_h, (int)img_w, CvType.CV_8UC3);
MatOfPoint2f cornerMat = new MatOfPoint2f(p0, p1, p2, p3); MatOfPoint2f quadMat = new MatOfPoint2f(new Point(imgWidth*0.4, imgHeight*1.6), new Point(imgWidth*0.4, imgHeight*0.4), new Point(imgWidth*1.6, imgHeight*0.4), new Point(imgWidth*1.6, imgHeight*1.6));
Mat transmtx = Imgproc.getPerspectiveTransform(cornerMat, quadMat); Imgproc.warpPerspective(src, rotated_image, transmtx, quad.size()); HighGui.imshow("Rotated image", rotated_image); HighGui.waitKey(0);
|