java - OpenCV getPerspectiveTransform 和 warpPerspective Java

标签 java opencv transformation perspective

我目前有一个 ArrayList<MatOfPoint>它存储图像的轮廓并检索到最大的轮廓,这是我的 warpPerspective 目标。

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(matOut, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

sort(contours);
MatOfPoint2f  m2f = MatOfPoint2f(contours.get(0).toArray());
double arc = Imgproc.arcLength(m2f, true);
MatOfPoint2f approx = new MatOfPoint2f();
Imgproc.approxPolyDP(m2f, approx, arc*0.02, true);

我在如何使用 getPerspectiveTransform 然后应用 warpPerspective 来更改图像以使其适合 450x450 图像方面遇到了问题。

我在 python 中找到了一个很好的例子,但是我不是很熟悉它有人可以解释我如何在 java 中进行纠正吗?

def rectify(h):
    ''' this function put vertices of square we got, in clockwise order '''
    h = h.reshape((4,2))
    hnew = np.zeros((4,2),dtype = np.float32)

    add = h.sum(1)
    hnew[0] = h[np.argmin(add)]
    hnew[2] = h[np.argmax(add)]

    diff = np.diff(h,axis = 1)
    hnew[1] = h[np.argmin(diff)]
    hnew[3] = h[np.argmax(diff)]

    return hnew

这是源链接:https://github.com/abidrahmank/OpenCV2-Python/blob/master/OpenCV_Python_Blog/sudoku_v_0.0.6/sudoku.py

最佳答案

简介:要使用 wrapPerspective,我们需要使用 getPerspectiveTransform 来计算环绕垫:Mat src 和 Mat dst。这些是 MatOfPoints2f 与 src(top-left, top-right, bottom-left, bottom-right) 你的轮廓和相应的 mat dst( 0,0 ; 0,449 ; 449,0 ; 449,449) (所以图像将是 450x450 -如果这是错误的,请纠正我)。

Solution 在 Java 中用于 opencv 3 的是:

  1. 对点进行排序 将矩形轮廓作为 MatOfPoints2f approx 我们需要按上面写的对点进行排序:

    //calculate the center of mass of our contour image using moments
    Moments moment = Imgproc.moments(approx.get(0));
    int x = (int) (moment.get_m10() / moment.get_m00());
    int y = (int) (moment.get_m01() / moment.get_m00());
    
    //SORT POINTS RELATIVE TO CENTER OF MASS 
    Point[] sortedPoints = new Point[4];
    
    double[] data;
    int count = 0;
    for(int i=0; i<approx.get(0).rows(); i++){
        data = approx.get(0).get(i, 0);
        double datax = data[0];
        double datay = data[1];
        if(datax < x && datay < y){
            sortedPoints[0]=new Point(datax,datay);
            count++;
        }else if(datax > x && datay < y){
            sortedPoints[1]=new Point(datax,datay);
            count++;
        }else if (datax < x && datay > y){
            sortedPoints[2]=new Point(datax,datay);
            count++;
        }else if (datax > x && datay > y){
            sortedPoints[3]=new Point(datax,datay);
            count++;
        }
    }
    
  2. 准备Mat src和det

            MatOfPoint2f src = new MatOfPoint2f(
                    sortedPoints[0],
                    sortedPoints[1],
                    sortedPoints[2],
                    sortedPoints[3]);
    
            MatOfPoint2f dst = new MatOfPoint2f(
                    new Point(0, 0),
                    new Point(450-1,0),
                    new Point(0,450-1),
                    new Point(450-1,450-1)      
                    );
    
  3. 使用 getPerspectiveTransform 和 wrapPrespective

        Mat warpMat = Imgproc.getPerspectiveTransform(src,dst);
        //This is you new image as Mat
        Mat destImage = new Mat();
        Imgproc.warpPerspective(originalImg, destImage, warpMat, originalImg.size());
    

我刚刚完成了类似的项目,所以我相信这可以做得更好,但如果有人需要的话,这是一个可行的解决方案。

关于java - OpenCV getPerspectiveTransform 和 warpPerspective Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40688491/

相关文章:

java - 在任何机器上查找连接限制的可靠方法

java - JPA直接返回query.getSingleResult()时返回null

java - 为什么java有new?

c++ - 错误 : insufficient memory opencv

java - 将我的代码(mac)中的绝对路径更改为我的电脑的相对路径

java - 导入 Eclipse 的 Maven 项目出现错误 "No GWT module found"

python - 使用PIL或Opencv以实色显示用HSV编码的图像

java - 降低双线性插值的时间复杂度

matlab - 将指针移动到对象上 (MATLAB)