2012-06-19 4 views
8

Ich entwickle Projekt mit Java, um Komponenten mit opencv-Paket zu identifizieren, aber ich bin neu bei Javacv und ich möchte nur wissen, wie Sie Rechtecke in einem bestimmten Quellbild identifizieren können bitte einige Erfahrung Person geben einige grundlegende Richtlinie, um dies zu archivieren Aufgabe. Ich versuche hier den Template-Abgleich zu verwenden, aber es kann nur ein Rechteck mit exakter Größe identifizieren. Aber in meinem Fall muss ich Rechteck mit variabler Länge identifizieren?Wie kann man mit javacv ein Quadrat oder ein Rechteck mit variabler Länge und Breite identifizieren?

import java.util.Arrays; 
import static com.googlecode.javacv.cpp.opencv_core.*; 
import static com.googlecode.javacv.cpp.opencv_imgproc.*; 
import static com.googlecode.javacv.cpp.opencv_highgui.*; 
public class TestingTemplate { 
public static void main(String[] args) { 
//Original Image 
IplImage src = cvLoadImage("src\\lena.jpg",0); 
//Template Image 
IplImage tmp = cvLoadImage("src\\those_eyes.jpg",0); 
//The Correlation Image Result 
IplImage result = cvCreateImage(cvSize(src.width()-tmp.width()+1, src.height()-tmp.height()+1), IPL_DEPTH_32F, 1); 
//Init our new Image 
cvZero(result); 
cvMatchTemplate(src, tmp, result, CV_TM_CCORR_NORMED); 

double[] min_val = new double[2]; 
double[] max_val = new double[2]; 

//Where are located our max and min correlation points 
CvPoint minLoc = new CvPoint(); 
CvPoint maxLoc = new CvPoint(); 
cvMinMaxLoc(result, min_val, max_val, minLoc, maxLoc, null); //the las null it's for 
optional mask mat() 

System.out.println(Arrays.toString(min_val)); //Min Score 
System.out.println(Arrays.toString(max_val)); //Max Score 

CvPoint point = new CvPoint(); 
point.x(maxLoc.x()+tmp.width()); 
point.y(maxLoc.y()+tmp.height()); 
cvRectangle(src, maxLoc, point, CvScalar.WHITE, 2, 8, 0); //Draw the rectangule result in original img. 
cvShowImage("Lena Image", src); 
cvWaitKey(0); 
//Release 
cvReleaseImage(src); 
cvReleaseImage(tmp); 
cvReleaseImage(result); 
} 
} 

kann Bitte jemand helfen diese

+2

Quadrate? Squires sind härter. –

+0

Dave: Bitte kannst du eine Gildenlinie zur Verfügung stellen, um diese zu archivieren> –

+2

Ist es Squire oder SQUARE? wenn nicht, was ist Squire? Google sagt, es ist eine Rüstung von Soldaten. Ist es das was du willst? Fügen Sie besser ein Bild hinzu. –

Antwort

9

zu erreichen (also als Platz fixiert ist.)

Für quadratische Detektion, kommt OpenCV mit einigen Proben dafür. Codes sind in C++, C, Python. Ich hoffe, Sie können dies auf JavaCV portieren.

C++ code, Python Code.

Ich will nur zeigen, wie es funktioniert:

1 - Sie setzen das Bild geteilt bis R, G, B-Ebene.

2 - dann für jede Ebene durchführen Kantendetektion und zusätzlich zu dem, Schwellenwert für verschiedene Werte wie 50, 100, .... usw.

3 - und in all diesen binären Bilder, finden Sie Konturen (denken Sie daran, es verarbeitet eine Menge Bilder, so kann ein bisschen langsam sein, wenn Sie nicht wollen, können Sie einige Schwellenwerte entfernen).

4 - Nachdem Sie Konturen gefunden haben, entfernen Sie einige kleine unerwünschte Geräusche durch Filtern nach Bereich.

5 - Dann, ungefähr die Kontur. (More about contour approximation).

6 - Für ein Rechteck erhalten Sie die vier Ecken. Für andere werden entsprechende Ecken angegeben.

So filtern Sie diese Konturen in Bezug auf die Anzahl der Elemente in approximierten Kontur, die vier sein sollte, die der Anzahl der Ecken entspricht. Erste Eigenschaft von Rechteck.

7 - Als nächstes gibt es einige Formen mit vier Ecken, aber keine Rechtecke. So nehmen wir zweite Eigenschaft von Rechtecken, dh alle inneren Winkel sind 90. So finden wir den Winkel an allen Ecken unter Verwendung der Beziehung unter:

enter image description here

Und wenn cos (theta) < 0,1, dh theta> 84 Grad, dass ein Rechteck ist.

8 - Was ist dann mit dem Quadrat? Verwenden Sie die Eigenschaft, dass alle Seiten gleich sind.

Sie können den Abstand zwischen zwei Punkten anhand der oben gezeigten Beziehung finden. Überprüfen Sie, ob alle gleich sind, dann ist das Rechteck ein Quadrat.

So funktioniert der Code.

Unten ist der Ausgang I auf einem Bild oben genannten Code bekam Anwendung:

enter image description here

EDIT:

Es wurde gebeten, wie das Rechteck an der Grenze erkannt zu entfernen. Das liegt daran, dass opencv weiße Objekte in schwarzem Hintergrund findet, also auch Border. Wenn Sie einfach das Bild mit der Funktion cv2.bitwise_not() invertieren, wird das Problem gelöst. erhalten wir das Ergebnis wie folgt:

enter image description here

Hier können Sie mehr Informationen zu Kontur finden: Contours - 1 : Getting Started

+0

Können Sie bitte erklären, wie ich Rechtecke mit weniger als spezifischer Breite erhalten kann? Eigentlich muss ich die großen Rechtecke entfernen, die im Bild (Grenzen) angezeigt werden. –

+0

Dieser große Rechteckrahmen wird erkannt, weil opencv Konturen weiße Objekte in schwarzem Hintergrund finden. Also machen Sie Quadrate weiß, dh invertieren Sie einfach das Bild. Ich habe die Antwort aktualisiert. –

+0

Also kann ich nicht jedes Rechteck einzeln bekommen? Wenn es möglich ist, können Sie ein Codebeispiel dafür bereitstellen. –

Verwandte Themen