2016-11-19 148 views
1

我現在有一個ArrayList<MatOfPoint>存儲圖像的輪廓,並取回這是我的目標warpPerspective最大的輪廓。OpenCV的getPerspectiveTransform和warpPerspective的Java

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

回答

1

介紹:利用wrapPerspective的,我們需要計算使用getPerspectiveTransform包裹墊需要:墊src和墊DST。這些是MarOfPoints2f,帶有src(左下角,右下角,左上角,右上角)輪廓和相應的mat dst(0,0; ​​0,449; 449,0; 449,449)(因此圖像將是450x450 - 如果這是錯誤的,請糾正我)。

解決方案在Java中的OpenCV的3將是:

  1. 獲得積分排序 由矩形輪廓MatOfPoints2f約我們需要的積分排序上面寫着:

    //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. 準備墊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()); 
    

我剛做完類似的項目,所以我相信這是可以做到更好,但它是一個可行的解決方案,如果有人需要一個。