Donnerstag, Februar 27, 2020

Konvexe Hülle auf Java Android Opencv 2.3

Bitte helfen Sie mir,

Ich habe ein problem, für Convex Hull auf Android. Ich benutze Java und OpenCV 2.3.

Bevor ich es auf Java, habe ich es auf C++ mit Visual Studio 2008.

Dieser code erfolgreich ausgeführt auf C++.

Nun, ich will es konvertieren von C++ zu Java auf Android. Und ich fand Fehlermeldung wie „force close“ wenn ich es laufen auf der Android SDK-simulator.

Dies ist mein code auf C++:

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
drawing = Mat::zeros( canny_output.size(), CV_64F );

///Find the convex hull object for each contour
vector<vector<Point> > hull ( contours.size() );
for( int i = 0; i < contours.size(); i++ )
  {  convexHull( Mat(contours[i]), hull[i], false );
}

for(size_t i = 0; i < contours.size(); i++){
    drawContours( drawing, hull, i, Scalar(255, 255, 255), CV_FILLED ); //FILL WHITE COLOR
}

Und das ist mein code auf Android:

Mat hierarchy = new Mat(img_canny.rows(),img_canny.cols(),CvType.CV_8UC1,new Scalar(0));
    List<Mat> contours =new ArrayList<Mat>();
    List<Mat> hull = new ArrayList<Mat>(contours.size());
    drawing = Mat.zeros(img_canny.size(), im_gray);

    Imgproc.findContours(img_dilasi, contours, hierarchy,Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));

    for(int i=0; i<contours.size(); i++){
        Imgproc.convexHull(contours.get(i), hull.get(i), false);

    }
    for(int i=0; i<contours.size(); i++){
        Imgproc.drawContours(drawing, hull, i, new Scalar(255.0, 255.0, 255.0), 5);
    }

Für deine info, ich habe eine kleine änderung auf der Konvexen Hülle an meinem code. Fülle ich eine Farbe im inneren Kontur.

Jemand kann mir helfen, mein problem zu lösen?

Ich bin für Eure Hilfe sehr dankbar.

  • Es ist schwer zu sagen, was die Ursache für dein problem. Was ist die spezifische Fehlermeldung, die Sie bekommen? Gibt es log-Ausgabe im Zusammenhang mit ihm?
  • Wenn ich es laufen auf der Android SDK-Simulator, windows-Fehler erschien, „die Anwendung gestopt unerwartet“ und mir wurde gesagt, zu stoppen, indem Sie auf „Force Close“. Und wenn ich überprüft, Log-Cat Fehler Eclipse, ich fand, dass der Prozess halt auf dieser Linie „Imgproc.convexHull(Konturen.get(i), hull.get(i), false);“ ich weiß nicht, warum der Vorgang gestopt, in der Zeile. Können Sie nicht helfen, mir erklären?
  • Ich denke ich habe einen Fehler bei der Deklaration der „Rumpf“ – variable. Aber, ich weiß nicht, wie man dieses problem lösen. Ich denke, ich habe erklärt, dass die variable in übereinstimmung mit den geltenden Bestimmungen. Was ist Ihre Meinung? Glauben Sie, dass die Deklaration einer variable „Rumpf“ in meinem code nicht richtig?
  • Hat einer von den Antworten, die Ihr problem lösen? Wenn ja, würden Sie akzeptieren einer von Ihnen? Wenn nicht, hinterlassen Sie bitte einen Kommentar unter Angabe, was wir verbessern können.
InformationsquelleAutor Jenang | 2013-07-11

6 Kommentare

  1. 10

    Nicht die rep hinzufügen, Kommentar, wollte nur sagen, dass die beiden oben genannten Antworten halfen mir Imgproc.convexHull() funktioniert für meinen Gebrauch Fall mit etwas wie folgt aus (2.4.8):

    MatOfPoint mopIn = ...
    MatOfInt hull = new MatOfInt();
    Imgproc.convexHull(mopIn, hull, false);
    
    MatOfPoint mopOut = new MatOfPoint();
    mopOut.create((int)hull.size().height,1,CvType.CV_32SC2);
    
    for(int i = 0; i < hull.size().height ; i++)
    {
        int index = (int)hull.get(i, 0)[0];
        double[] point = new double[] {
            mopIn.get(index, 0)[0], mopIn.get(index, 0)[1]
        };
        mopOut.put(i, 0, point);
    }           
    //do something interesting with mopOut
  2. 2

    Dieser code funktioniert in meiner Anwendung. In meinem Fall hatte ich mehrere Konturen, mit zu arbeiten, so werden Sie feststellen, eine Menge von Listen, aber wenn Sie nur eine Kontur, so passen Sie es zu arbeiten, ohne .get(i) Iterationen.

    Diesem thread erklärt, der Prozess einfach.

    android-java, opencv 2.4 convexhull convexdefect

       //Find the convex hull
                List<MatOfInt> hull = new ArrayList<MatOfInt>();
                for(int i=0; i < contours.size(); i++){
                    hull.add(new MatOfInt());
                }
                for(int i=0; i < contours.size(); i++){
                    Imgproc.convexHull(contours.get(i), hull.get(i));
                }
    
                //Convert MatOfInt to MatOfPoint for drawing convex hull
    
                //Loop over all contours
                List<Point[]> hullpoints = new ArrayList<Point[]>();
                for(int i=0; i < hull.size(); i++){
                    Point[] points = new Point[hull.get(i).rows()];
    
                    //Loop over all points that need to be hulled in current contour
                    for(int j=0; j < hull.get(i).rows(); j++){
                        int index = (int)hull.get(i).get(j, 0)[0];
                        points[j] = new Point(contours.get(i).get(index, 0)[0], contours.get(i).get(index, 0)[1]);
                    }
    
                    hullpoints.add(points);
                }
    
                //Convert Point arrays into MatOfPoint
                List<MatOfPoint> hullmop = new ArrayList<MatOfPoint>();
                for(int i=0; i < hullpoints.size(); i++){
                    MatOfPoint mop = new MatOfPoint();
                    mop.fromArray(hullpoints.get(i));
                    hullmop.add(mop);
                }
    
    
                //Draw contours + hull results
                Mat overlay = new Mat(binaryImage.size(), CvType.CV_8UC3);
                Scalar color = new Scalar(0, 255, 0);   //Green
                for(int i=0; i < contours.size(); i++){
                    Imgproc.drawContours(overlay, contours, i, color);
                    Imgproc.drawContours(overlay, hullmop, i, color);
                }
  3. 2

    Beispiel in Java (OpenCV 2.4.11)

    hullMat enthält die sub-mat von gray, die durch die convexHull Methode.
    Können Sie filtern möchten, die Konturen, die Sie wirklich brauchen, beispielsweise basierend auf Ihrer Region.

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    MatOfInt4 hierarchy = new MatOfInt4();
    MatOfInt hull = new MatOfInt();
    
    void foo(Mat gray) {
        Imgproc.findContours(gray, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);        
        for (int i = 0; i < contours.size(); i++) {
            Imgproc.convexHull(contours.get(i), hull);
            MatOfPoint hullContour = hull2Points(hull, contours.get(i));
            Rect box = Imgproc.boundingRect(hullContour);
            Mat hullMat = new Mat(gray, box);
            ...
        }
    }
    
    MatOfPoint hull2Points(MatOfInt hull, MatOfPoint contour) {
        List<Integer> indexes = hull.toList();
        List<Point> points = new ArrayList<>();
        MatOfPoint point= new MatOfPoint();
        for(Integer index:indexes) {
            points.add(contour.toList().get(index));
        }
        point.fromList(points);
        return point;
    }
  4. 1

    Suchen Sie in der Dokumentation des findContours() und convexHull(), es scheint, dass Sie deklariert die Variablen contours und hull falsch.

    Versuchen Sie, die Erklärungen zu:

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    List<MatOfInt> hull = new ArrayList<MatOfInt>();

    Dann, nach rufen Sie convexHull(), hull enthält die Indizes der Punkte in contours die sich aus der konvexen Hülle. Damit zeichnen Sie die Punkte mit drawContours() wird, müssen Sie füllen eine neue MatOfPoint enthält nur die Punkte auf der konvexen Hülle, und pass auf drawContours(). Ich überlasse dies als übung für Sie.

  5. 1

    Hinzufügen zu dem, was Aurelius sagte, in der C++ – Implementierung, die Sie verwendet einen Vektor von Punkten, also die Rumpf-matrix enthält die eigentliche konvexe Punkte:

    „Im ersten Fall [integer Vektor der Indizes], die Rumpf-Elemente sind 0-basierte Indizes der konvexen Hülle der Punkte in der ursprünglichen Arrays (da die Menge der konvexen Hülle der Punkte ist eine Teilmenge der originalen Punktmenge). Im zweiten Fall [Vektor von Punkten], Rumpf-Elemente sind die konvexe Hülle der Punkte selbst.“ – convexHull

    Dies ist der Grund, warum Sie waren in der Lage zu nennen

    drawContours( drawing, hull, i, Scalar(255, 255, 255), CV_FILLED );

    In Ihrer android-version, die Rumpf-Ausgang ist einfach ein array von Indizes, die entsprechen der Punkte in den ursprünglichen Konturen.get(i) Matrix. Daher müssen Sie, um die konvexe Punkte in der ursprünglichen matrix. Hier ist eine sehr grobe Idee:

    MatOfInt hull = new MatOfInt();
    MatOfPoint tempContour = contours.get(i);
    Imgproc.convexHull(tempContour, hull, false); //O(N*Log(N))
    //System.out.println("hull size: " + hull.size() + " x" + hull.get(0,0).length);
    //System.out.println("Contour matrix size: " + tempContour.size() + " x" + tempContour.get(0,0).length);
    
    int index = (int) hull.get(((int) hull.size().height)-1, 0)[0];
    Point pt, pt0 = new Point(tempContour.get(index, 0)[0], tempContour.get(index, 0)[1]);
    for(int j = 0; j < hull.size().height -1 ; j++){
        index = (int) hull.get(j, 0)[0];
        pt = new Point(tempContour.get(index, 0)[0], tempContour.get(index, 0)[1]);
        Core.line(frame, pt0, pt, new Scalar(255, 0, 100), 8);
        pt0 = pt;
    }
  6. -1

    Verwenden Sie diese fillconvexPoly

     for(;;){
              Imgproc.fillConvexPoly(image_2, point,new Scalar(255, 255, 255));
        }

Kostenlose Online-Tests