0

Ich benutze OpenCV4Android Version 2.4.11 und ich erkenne alle rechteckigen Formen in Frames von der Kamera abgerufen. Wie in Bild_1 unten gezeigt, zeichne ich eine Kontur einer schwarzen Farbe um das erkannte Objekt, und was ich zu tun versuche, ist , um alle Koordinaten der gezeichneten Kontur zu erhalten, die NUR in Schwarz gezeichnet wird. Was ich versuchte, ist, wie in code_1 unten gezeigt, ich die größte Kontur und den Index der größten Kontur und speichern Sie sie in der "largeContour" und "large_contour_index" jeweils. Dann ziehe ich die KonturWie bekomme ich die Koordinaten einer Kontur?

Imgproc.drawContours(mMatInputFrame, contours, largest_contour_index, new Scalar(0, 0, 0), 2, 8, hierachy, 0, new Point()); 

verwenden und dann gebe ich Punkte der größten Kontur der Klasse FindCorners, weil ich die spezifischen Koordinaten der Kontur in schwarz gezeichnet finden wollen, wie folgt:

this.mFindCorners = new FindCorners(largestContour.toArray()); 
double[] cords = this.mFindCorners.getCords(); 

die folgende Codezeile:

double[] cords = this.mFindCorners.getCords(); 

soll, gibt mir die smallen x-Koordinaten, kleinste y-Koordinaten, größte x-Koordinaten und größten y-Koordinaten. Aber wenn ich einen Kreis um die Koordinaten zeichne, habe ich von "this.mFindCorners.getCords();" Ich habe etwas wie in image_2 unten, das sind nur die Ecken des BoundingRect.

Eigentlich will ich keine Koordinaten aus dem boundingRect i auf die Koordinaten der Kontur haben Zugriff möchten, die

um das erfasste Objekt in Balck gezogen wird

lassen Sie es mich wissen, wie die Koordinaten der Kontur zu erhalten selbst?

CODE_1:

if (contours.size() > 0) { 
     for (int i = 0; i < contours.size(); i++) { 
      contour2f = new MatOfPoint2f(contours.get(i).toArray()); 
      approxDistance = Imgproc.arcLength(contour2f, true) * .01;//.02 
      approxCurve = new MatOfPoint2f(); 
      Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true); 
      points = new MatOfPoint(approxCurve.toArray()); 

      double area = Math.abs(Imgproc.contourArea(points, true)); 
      if (points.total() >= 4 && area >= 40000 && area <= 200000) { 
       if (area > largest_area) { 
        largest_area = area; 
        largest_contour_index = i; 
        pointsOfLargestContour = points; 
        largestContour = contours.get(i); 
       } 
      } 
     } 

     if (largest_area > 0) { 
      Imgproc.drawContours(mMatInputFrame, contours, largest_contour_index, new Scalar(0, 0, 0), 2, 8, hierachy, 0, new Point()); 

      this.mFindCorners = new FindCorners(largestContour.toArray()); 
      double[] cords = this.mFindCorners.getCords(); 

      Core.circle(mMatInputFrame, new Point(cords[0], cords[1]), 10, new Scalar(255, 0, 0)); 
      Core.circle(mMatInputFrame, new Point(cords[2], cords[3]), 10, new Scalar(255, 255, 0)); 
     } 

FindCorners:

public class FindCorners { 
private final static String TAG = FragOpenCVCam.class.getSimpleName(); 

private ArrayList<Double> mlistXCords = null; 
private ArrayList<Double> mlistYCords = null; 
private double mSmallestX; 
private double mSmallestY; 
private double mLargestX; 
private double mLargestY; 
private double[] mCords = null; 

public FindCorners(Point[] points) { 
    this.mlistXCords = new ArrayList<>(); 
    this.mlistYCords = new ArrayList<>(); 
    this.mCords = new double[4]; 

    Log.d(TAG, "points.length: " + points.length); 

    for (int i = 0; i < points.length; i++) { 
     this.mlistXCords.add(points[i].x); 
     this.mlistYCords.add(points[i].y); 
    } 

    //ascending 
    Collections.sort(this.mlistXCords); 
    Collections.sort(this.mlistYCords); 

    this.mSmallestX = this.mlistXCords.get(0); 
    this.mSmallestY = this.mlistYCords.get(0); 
    this.mLargestX = this.mlistXCords.get(this.mlistXCords.size() - 1); 
    this.mLargestY = this.mlistYCords.get(this.mlistYCords.size() - 1); 

    this.mCords[0] = this.mSmallestX; 
    this.mCords[1] = this.mSmallestY; 
    this.mCords[2] = this.mLargestX; 
    this.mCords[3] = this.mLargestY; 
} 

public double[] getCords() { 
    return this.mCords; 
} 

}

image_1:

enter image description here

image_2:

enter image description here

Update ich will nicht die Koordinaten des Begrenzungs rect haben, was ich haben will, ist, die genauen Koordinaten der schwarzen Kontur . Wie in Bild_3 gezeigt, sind die Koordinaten, die ich von meinem Code bekomme, wo die roten und gelben Kreise sind..aber ich suche nach Zugriff auf die Koordinaten der schwarzen Linie "Kontur", so dass ich einige Kreise darauf zeichnen kann, wie in gezeigt Bild_3. Die grünen Punkte zeigen dir nur, wo ich Koordinaten haben möchte.

image_3:

enter image description here

+0

_should gibt mir die smallen x-Koordinaten, kleinste y-Koordinaten, größte x-Koordinaten und größten y-coordinates._ Dieses ** ** sind die Koordinaten des Begrenzungs Box. Sie wollen wahrscheinlich die 4 Ecken nach 'approxPolyDP' statt – Miki

+0

@Miki, wie Sie in meinem Code sehen, habe ich die folgende Zeile" Imgproc.approxPolyDP (contour2f, approxCurve, approxDistance, true); " ist die schwarze Kontur in "approxCurve" enthalten ?? – user2121

+0

die schwarze Kontur ist 'größteContour' – Miki

Antwort

0

Ihr Problem ist, dass man separat x und y die sortiert haben und es ist offensichtlich, dass Ihr Algorithmus die roten und gelben Punkten finden. Ich kann den folgenden Algorithmus vorschlagen:

int min_x=INF, min_x_index, min_y=1000, min_y_index; 
int max_x=-1, max_x_index, max_y=-1, max_y_index; 
for (int i = 0; i < points.length; i++) 
    { 
     if(points[i].x < min_x) { min_x = points[i].x; min_x_index = i; } 
     if(points[i].x > max_x) { max_x = points[i].x; max_x_index = i; } 
     if(points[i].y < min_y) { min_y = points[i].y; min_y_index = i; } 
     if(points[i].y > max_y) { max_y = points[i].y; max_y_index = i; } 
    } 
Point corner1(points[min_x_index]); 
Point corner2(points[min_y_index]); 
Point corner3(points[max_x_index]); 
Point corner4(points[max_y_index]); 
Verwandte Themen