有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java既没有找到最大矩形的轮廓,也没有通过hough变换进行角点检测

我一直在尝试检测点击图像上最大的矩形/正方形。我尝试了轮廓Android OpenCV Find Largest Square or Rectangle和霍夫变换http://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/

这两个作品都是从画廊中挑选出来的。但当我把从相机拍摄的图像整合起来时,大多数情况下都会失败

有谁能告诉我背后的原因吗?我错过了什么

据我所知,像camscanner这样的许多扫描应用程序都可以以超过90%的准确率完美地完成这项工作

请建议。我试了很多

供参考:

public static String houghTransform(Mat original_image ,String outFile) {
        Mat imgSource = original_image;
        Mat untouched = original_image.clone();

        //convert the image to black and white
        Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);


        //apply gaussian blur to smoothen lines of dots
        Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 0); 

        //adaptive threshold thresholds the image taking an optimum value for a local neighbourhood. 
        //Imgproc.adaptiveThreshold(imgSource, imgSource, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 3, 1);

        //convert the image to black and white does (8 bit)
        Imgproc.Canny(imgSource, imgSource, 80, 100);
        Mat lines = new Mat();
        int threshold = 70;
        int minLineSize = 20;
        int lineGap = 20;

        Imgproc.HoughLinesP(imgSource, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);

        ArrayList<Point> corners = new ArrayList<Point>();
        for (int i = 0; i < lines.cols(); i++)
        {
            for (int j = i+1; j < lines.cols(); j++)
            {
                Point pt = computeIntersect(lines.get(0,i), lines.get(0,j));
                if (pt.x >= 0 && pt.y >= 0)
                    corners.add(pt);
            }
        }
        L.v("Points corner size: ", ""+corners.size());
        if(corners.size()<4){
            return "";
        }

        Point center = new Point(0,0);
        // Get mass center
        for (int i = 0; i < corners.size(); i++){
            center.x += corners.get(i).x;
            center.y+= corners.get(i).y;
        }
        center.x = (center.x / corners.size());
        center.y = (center.y / corners.size());

        Core.circle(untouched, center, 20, new Scalar(255, 0, 0), 5); //p1 is colored red

        Core.circle(untouched, corners.get(0), 20, new Scalar(255, 0, 0), 5); 
        Core.circle(untouched, corners.get(1), 20, new Scalar(255, 0, 0), 5); 
        Core.circle(untouched, corners.get(2), 20, new Scalar(255, 0, 0), 5); 
        Core.circle(untouched, corners.get(3), 20, new Scalar(255, 0, 0), 5);

        Highgui.imwrite(outFile, untouched);
         return outFile;

 } 

这里是computerIntersect模块,用于检测四个角点

  private static Point computeIntersect(double[] a, double[] b) {
    double x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
    double denom = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
    Point pt = new Point();
    if (denom!=0)
    {

            pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denom;
            pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denom;
            return pt;
    }
    else
            return new Point(-1, -1);
}

在这里,当我将其应用于从相机拍摄的图像时,它会返回四个以上的点

我尝试过的另一种方法是:

  public static String findLargestRectangle(Mat original_image ,String outFile) {
        Mat imgSource = original_image;
        Mat untouched = original_image.clone();

        //convert the image to black and white
        Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);


        //apply gaussian blur to smoothen lines of dots
        Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 0); 

        //convert the image to black and white does (8 bit)
        Imgproc.Canny(imgSource, imgSource, 80, 100);

            //find the contours
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

        double maxArea = -1;
        int maxAreaIdx = -1;

        MatOfPoint temp_contour = contours.get(0); //the largest is at the index 0 for starting point
        MatOfPoint2f approxCurve = new MatOfPoint2f();
        MatOfPoint2f maxCurve = new MatOfPoint2f();
        List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
        for (int idx = 0; idx < contours.size(); idx++) {
            temp_contour = contours.get(idx);
            double contourarea = Imgproc.contourArea(temp_contour);
            //compare this contour to the previous largest contour found
            if (contourarea > maxArea) {
                // Imgproc.drawContours(untouched, contours, maxAreaIdx, new Scalar(0, 255, 0), 1); 
                //check if this contour is a square
                MatOfPoint2f new_mat = new MatOfPoint2f( temp_contour.toArray() );
                int contourSize = (int)temp_contour.total();
                Imgproc.approxPolyDP(new_mat, approxCurve, contourSize*0.05, true);
                if (approxCurve.total() == 4) {
                    maxCurve = approxCurve;
                    maxArea = contourarea;
                    maxAreaIdx = idx;
                    largest_contours.add(temp_contour);
                }
            }
        }
  Imgproc.drawContours(imgSource, contours, maxAreaIdx, new Scalar(0, 255, 0), 5); //will draw the largest square/rectangle
 }

谢谢

enter image description here enter image description here


共 (0) 个答案