2016-05-24 18 views
4

Dies muss für C++ - Entwickler, die OpenCV direkt verwenden, einfach sein. Was ich jedoch benutze, ist Emgu (ein OpenCV-Wrapper für .NET) und in der neuesten Version haben wir die Methode CvInvoke.FindContours, die void zurückgibt, das Ausgabeergebnis wird von Parameterreferenz übergeben und hat den Typ VectorOfVectorOfPoint.Navigieren durch die Hierarchie der Konturen, die von der FindContours-Methode gefunden wurden?

Hier ist ein einfacher Aufruf:

//outputResult is a VectorOfVectorOfPoint 
CvInvoke.FindContours(inputImage, outputResult, null, RetrType.Tree, 
         ChainApproxMethod.ChainApproxSimple); 

Für RetrType.List-Modus können wir das Ergebnis bis zu einem gewissen Array von Arrays und eine Schleife durch alle Konturen leicht umbauen. Aber hier möchte ich durch alle Konturen in einem Baum navigieren. Ich denke, wir müssen etwas mit nativem (unsicheren) C++ Code hier mit Zeiger (Zugriff über die Ptr Eigenschaft des Ausgangsergebnisses) tun. Aber ich frage mich, ob es dafür eine .NET-freundliche Lösung gibt. Und wenn sogar die Verwendung von Pointer die einzige Lösung ist, weiß ich immer noch nicht, wie ich in diesen Ptr eintauchen soll, um durch den Konturenbaum zu navigieren.

Die Beispielcodes, die mit der Emgu-Installation einhergehen, enthalten stattdessen ein Snippet, das CvInvoke.FindContourTree verwendet (und das eine int[,] zurückgibt).

+1

Wird die Hierarchie nicht im dritten Parameter ausgegeben, den Sie auf null setzen? Sie können countours genauso aufzählen, ob Sie RetrType.List oder Tree verwenden, um Hierarchieinfo zu erhalten, eine neue Variable vom Typ Mat zu erstellen und diese als dritten Parameter (der jetzt null ist) übergeben. – Evk

+0

@Evk Ja, mir war nicht klar, dass ich auf der dritten Position vorbeigehen sollte, und selbst wenn ich davon wüsste, hätte ich nicht gewusst, um welchen Typ es sich handelt. Jetzt lassen Sie mich wissen, ich sollte in einer 'Mat' passen. Aber ich habe gerade versucht, mehr über diesen Typ zu finden, und es scheint keine einfach zu erkennenden Mitglieder zu haben, die mir helfen, durch den Baum zu navigieren. Wenn möglich, geben Sie mir bitte einen Beispielcode in Ihrer Antwort. Das wäre sehr geschätzt. Vielen Dank! – Hopeless

Antwort

6

die Hierarchie der Konturen zu erhalten, müssen Sie zunächst ein Mat Objekt an die Funktion übergeben:

Mat hierarchy = new Mat() ; 
CvInvoke.FindContours(inputImage, outputResult, hierarchy, RetrType.Tree, 
        ChainApproxMethod.ChainApproxSimple); 

Dann können Sie das hierarchy-Objekt verwenden, wie folgt (siehe here für weitere Details in Python OpenCV):

hierarchy wird ein Mat Objekt der Größe 1 x Größe outputResult x 4. sein also für die Kontur mit dem Index i:

  • hierachy[0,i,0] ist, den Index der nächsten Kontur auf der gleichen Hierarchieebene (mit dem gleichen parent) oder - 1, wenn es nicht
  • hierachy[0,i,1] existiert der Index der vorherigen Kontur auf der gleichen Hierarchieebene ist, oder - 1, wenn es nicht
  • hierachy[0,i,2] ist der Index des Kindes von Kontur i oder nicht vorhanden ist - 1, wenn es nicht
  • i oder
  • hierachy[0,i,3] ist der Index der Mutter der Kontur existiert - 1, wenn es nicht der Fall ist exist

So verwenden Sie das Hierarchieobjekt.

Auf die Konturen selbst wird über das Objekt outputResult zugegriffen, indem ihre Indizes verwendet werden.

+0

Sind Sie sicher, dass "Mat" einen Indexer hat, der 3 Argumente akzeptiert?Ich habe versucht, eine einfache Variable von 'Mat' zu deklarieren und etwas so zu schreiben wie 'm [0,0,0]' verursacht einige Entwurfszeitfehler und natürlich kann es nicht sogar kompilieren. Was du vorgeschlagen hast, könnte gültig sein und in Python funktionieren, aber hier frage ich in C#. Vielen Dank! – Hopeless

+0

Haben Sie 'm.Data [0,0,0]' versucht? Ich kann es nicht mit C# testen, aber einige Antworten online scheinen zu sagen, dass das möglich ist. – Sunreef

+0

'm.Data' ist ein' Array', das verschiedene Dimensionen (Rang) haben kann, also wahrscheinlich einen Rang von '3' hat, aber dann müssen wir die Methode' GetValue' verwenden ('Array' hat auch keine) jeder Indexer akzeptiert 3 Argumente). Allerdings habe ich versucht, meinen Code und 'm.Data' ist eigentlich' null' was unmöglich ist, wenn eine Baumstruktur erreicht werden soll, das bedeutet 'm.Data' ist nicht wo die Baumdaten zu ziehen. Diese 'Map' ist für mich ziemlich kompliziert, sie ist eine Art allgemeiner Zweckklasse, daher ist es schwer zu wissen, wie man sie in diesem spezifischen Szenario benutzt. – Hopeless