无法获得warpPerspective以获得正确的转换

时间:2017-06-29 23:38:05

标签: java android opencv image-processing perspective

已经尝试过在网上找到的所有选项。 坐标是正确的。向量上的顺序相等。 Before and after 我错过了什么?

GetComponentsInChildren<T>()

2 个答案:

答案 0 :(得分:0)

我想,你得错了。所以,我建议尝试下面的代码:

 MatOfPoint2f thisContour2f = new MatOfPoint2f();
        MatOfPoint2f approxContour2f = new MatOfPoint2f();

    contours.get(maxI).convertTo(thisContour2f, CvType.CV_32FC2); // here contours is a List of MatOfPoint which you get from ImgProc.findContours() method.
    Imgproc.approxPolyDP(thisContour2f, approxContour2f, Imgproc.arcLength(thisContour2f, true) * 0.01, true); // Approximates a polygonal curve(s) with the specified precision. since you have to detect document which is rectangle , you need to find four points

    if (approxContour2f.size().height == 4) { // since we are detecting rectangle , check wether contours has 4 points

    MatOfPoint2f rotatedMat = new MatOfPoint2f(contours.get(maxI).toArray());
            RotatedRect boundingBox = Imgproc.minAreaRect(rotatedMat);  // find RotatedRect from contours 

        double[] temp_double;                       // find four points
                    temp_double = approxContour2f.get(0, 0);
                    Point p1 = new Point(temp_double[0], temp_double[1]);

                    temp_double = approxContour2f.get(1, 0);
                    Point p2 = new Point(temp_double[0], temp_double[1]);

                    temp_double = approxContour2f.get(2, 0);
                    Point p3 = new Point(temp_double[0], temp_double[1]);

                    temp_double = approxContour2f.get(3, 0);
                    Point p4 = new Point(temp_double[0], temp_double[1]);

        List<Point> source = new ArrayList<>();
                    source.add(p1);
                    source.add(p2);
                    source.add(p3);
                    source.add(p4);

        Mat startM = Converters.vector_Point2f_to_Mat(source);        
`       Mat result = warp(mRgba, startM, boundingBox.boundingRect());  // mrgba is a original mat

     }

现在,您可以从warp()函数下面查看它:

public Mat warp(Mat inputMat, Mat startM, Rect rect) {

    int resultWidth = rect.width;
    int resultHeight = rect.height;

    Point ocvPOut4, ocvPOut1, ocvPOut2, ocvPOut3;

    ocvPOut1 = new Point(0, 0);
            ocvPOut2 = new Point(0, resultHeight);
            ocvPOut3 = new Point(resultWidth, resultHeight);
            ocvPOut4 = new Point(resultWidth, 0);

    Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC4);

    List<Point> dest = new ArrayList<Point>();
    dest.add(ocvPOut1);
    dest.add(ocvPOut2);
    dest.add(ocvPOut3);
    dest.add(ocvPOut4);
    Mat endM = Converters.vector_Point2f_to_Mat(dest);

    Mat perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM);

    Imgproc.warpPerspective(inputMat, outputMat, perspectiveTransform, new Size(resultWidth, resultHeight), Imgproc.INTER_CUBIC);

    return outputMat;
}
希望它会有所帮助!!

答案 1 :(得分:0)

经过长时间的斗争,终于找到了问题。

请发布到这里。也许在我的情况下帮助某人。

问题是:我使用了视图的坐标。并且需要位图的坐标。这使得经线完全疯狂的行为。所以只是从View的coords翻译成Bitmaps的。现在它很完美:

float xRatio=(float)bitmap.getWidth()/cropPanel.getWidth();
float yRatio=(float)bitmap.getHeight()/cropPanel.getHeight();

for (int i=0;i<4;i++)
    corners.add(new Point(cropPanel.corners[i].x*xRatio,cropPanel.corners[i].y*yRatio);

List<Point> target=new ArrayList<>();
target.add(new Point(0,0));
target.add(new Point(bitmap.getWidth(),0));
target.add(new Point(bitmap.getWidth(),bitmap.getHeight()));
target.add(new Point(0,bitmap.getHeight()));