Das Eingangsbild wird mit einer Bitmaske über mehrere Farbkanäle bearbeitet. Es werden alle Pixel - welche die folgenden Schwellwerte nicht überschreiten - schwarz, bzw. transpartent überschrieben.
Rot | Grün | Blau |
---|---|---|
< 133 | < 133 | < 150 |
Hier ein Beispiel anhand des Bildes "Bildname" aus dem Datensatz.
Wieso hier Graubildumwandlung?
Das maskierte Bild wird darauf in die openCV Funktion cv2.findContours()
übergeben, welche eine Bloberkennung umsetzt. Mit Hilfe dieser Bloberkennung ist die genaue Bestimmung der Position des PCBs möglich, indem nur der Blob mit einer größten Fläche akzeptiert wird.
Um diesen Blob zur weiteren Verarbeitung verwenden zu können, muss der Blob wieder in ein Rechteck umgewandelt werden (boundary_box.py). Hierfür wurde die Funktion cv2.minAreaRect()
eingesetzt, welche ein Rechteck ausgibt, welches optimal gedreht ist, um alle Pixel eines Blobs mit der kleinsten Fläche zu umschließen (Boundingbox). Es stellt sich nur das Problem, dass Ausreißer in dem Bild zu einem verdrehten Rechteck führen können.
(Beispielbild schief einfügen)
In diesem Schritt wird das Rechteck auf 0° Drehung korregiert. Dazu wird mit dem Winkel aus dem vorigen Schritt eine Rotationsmatrix erstellt (cv2.getRotationMatrix2D())
und auf das Bild angewendet. Es wurde bloß ein extra eingefügt (>45° -> -90°).
Nun wird die Erkennung der Boundingbox auf das gedrehte Bild angewand.
Nun wird align wieder ausgeführt, dieses mal jedoch auf das Originalbild, um den Hintergrund und die originalen Farben des Bildes bei zu behalten.
Folgend kann das Bild zugeschnitten werden. Hierfür wird ein optimales Seitenverhältnis von w / h = 980 / 580 = 1,69 vorgegeben. Stimmt dieses nicht mit der Bounding Box überein, wird diese auf das entsprechende Verhältnis nach oben erweitert. Darauf wird das Bild auf diese Bounding Box ausgeschnitten.
Nach dem align wird das PCB zwar horizontal orientiert, die Pins können aber noch oben oder unten liegen. Es wird der Schwerpunkt des Blobs auf dem Zugeschnittenen Bild berechnet und liegt dieser oberhalb der Bildmitte, wird das Bild um 180° gedreht.
Folgend werden alle bilder mit cv2.resize()
auf 980 x 580 skaliert.
Es wurde in dem feature/SVM Branch versucht, eine Klassifizierung mit einem SVM zu realisieren. Dafür war der Ansatz, die SVM auf jedes Bild einzeln zu trainieren, sodass sich die Grenzen der SVM an die Grenzen des PCBs anschmiegen. Dies hat jedoch nicht funktioniert, da die Punkte alle auf der Grenze des PCBs liegen und nicht im PCB. Stattdessen hätte der Ansatz mit einer direkten Analyse des Blobs auf die Binärmaske ausprobiert werden können.
Mit dem Ansatz in feature/Blobanalyse soll die Erkennung der Eckpunkte gesteigert werden. Hierfür werden die Winkel der Konturpunkte (vom Schwerpunkt aus) berechnet und in 1° Schritten abgetastet.
Darauf werden vom original Schwerpunkt im Bereich von +-10° nach dem Wert mit dem weitesten Abstand gesucht und als neuer Eckpunkt definiert. Der Ansatz wurde jedoch nicht zu Ende geführt, da sich die ermittelten Werte nicht von den zuvor berechneten Eckpunkten unterschieden.