2016-11-19 6 views
1

Ich habe derzeit eine ArrayList<MatOfPoint>, die die Konturen des Bildes speichert und die größte Kontur abgerufen hat, die mein Ziel für die WarpPerspektive ist.OpenCV getPerspectiveTransform und 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); 

Ich habe Probleme, wie den getPerspectiveTransform verwenden und dann die warpPerspective Anwendung das Bild zu ändern, so dass es in einem 450x450 Bild passen.

Ich fand ein ziemlich gutes Beispiel dafür in Python, aber ich bin nicht sehr vertraut damit kann jemand erklären, wie ich in Java korrigieren würde?

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 

hier ist die Quelle Link: https://github.com/abidrahmank/OpenCV2-Python/blob/master/OpenCV_Python_Blog/sudoku_v_0.0.6/sudoku.py

Antwort

1

Intro: Mat src und Mat dst: Verwendung von wrapPerspective wir Matte getPerspectiveTransform nimmt berechnen müssen, um wickeln. Das sind MarOfPoints2f mit src (unten links, unten rechts, oben links, oben rechts) deiner Kontur und der entsprechenden Matte dst (0,0; 0,449; 449,0; 449,449) (also das Bild wird 450x450 - Wenn das falsch ist, korrigiere mich bitte).

Lösung in Java für opencv 3 wäre:

  1. Get Punkten sortiert rechteckige Kontur als MatOfPoints2f ca. wir sortieren brauchen, um die Punkte zu haben, wie oben geschrieben:

    //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. Vorbereiten Mat src und 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. Verwenden getPerspectiveTransform und 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()); 
    

Ich habe gerade ähnliches Projekt abgeschlossen Dabei bin ich sicher, das besser getan werden kann, aber es ist eine funktionierende Lösung, wenn jemand braucht.