Objekte zu ihrer Längsachse vertikal ausrichten
Objekte fallen an einer Kamera vorbei.
Diese Objekte sollen für die anschliessende Vermessung, Erkennung und Visualisierung zu ihrer Längsachse vertikal ausgerichtet werden, also so, als würden diese Objekte immer vertikal zu ihrer Längsachse fallen. Ich habe eine funktionierende Methode. Mit 'LineDDA' wird geprüft, welche 'gedachte' Linie die längste ist, als Resultat erhält man einen Drehwinkel, mit dem das Objekt ausgerichtet wird. Gibt es einen besseren Weg? Danke für eure Antworten.
Delphi-Quellcode:
Procedure CheckPoints(X,Y: Integer; Canvas: TCanvas); StdCall;
var R, G, B:Byte; Color:TColor; begin {$R-} Color := Canvas.Pixels[X, Y]; R := GetRValue(Color); G := GetGValue(Color); B := GetBValue(Color); // prüfe, ob Pixelfarbe <> BackgroundTRGBFillColor if (R <> MainForm.BackgroundTRGBFillColor.r) and (G <> MainForm.BackgroundTRGBFillColor.g) and (B <> MainForm.BackgroundTRGBFillColor.b) then Inc(Distance); {$R+} end; Procedure TMainForm.AlignVertically(var bmp:TBitmap; var angle:Double); var X1, Y1, X2, Y2, MaxDist,Vektor:Cardinal; begin maxDist := 0; angle := 0; for Vektor := 1 to 8 do begin Distance := 1; if Vektor = 1 then begin // keine Drehung OK X1 := bmp.Width div 2; Y1 := 0; X2 := X1; Y2 := bmp.Height; //TFNLineDDAProc LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := 0; end; end; if Vektor = 2 then begin // Drehung um 90° OK // Horizontal gemessen = grösste Distanz > Drehung um 90° X1 := 0; Y1 := bmp.Height div 2; X2 := bmp.Width; Y2 := Y1; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := 90; end; end; if Vektor = 3 then begin // Drehung um 45° OK X1 := 0; Y1 := 0; X2 := bmp.Width; Y2 := bmp.Height; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := 315; end; end; if Vektor = 4 then begin X1 := bmp.Width div 4; Y1 := 0; X2 := X1 * 3; Y2 := bmp.Height; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := 337.5; end; end; if Vektor = 5 then begin // OK ? X2 := bmp.Width div 4; X1 := X2 * 3; Y1 := 0; Y2 := bmp.Height; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := -340; end; end; if Vektor = 6 then begin // Drehung um -45° OK X1 := bmp.Width; Y1 := 0; X2 := 0; Y2 := bmp.Height; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := -135; end; end; if Vektor = 7 then begin // OK ? X1 := 0; Y1 := bmp.Height div 4; X2 := bmp.Width; Y2 := Y1 * 3; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := 300; end; end; if Vektor = 8 then begin // OK ? X1 := 0; Y2 := bmp.Height div 4; Y1 := Y2 * 3; X2 := bmp.Width; LineDDA(X1, Y1, X2, Y2, @CheckPoints, LongInt(bmp.Canvas)); if Distance >= maxDist then begin maxDist := Distance; angle := -300; end; end; end; end; |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Zitat:
Außerdem wären ein paar Infos hilfreich Fällt immer nur ein Objekt an der Kamera vorbei oder gibt es mehrere gleichzeitig. Das die Ausrichtung veränderlich ist hat Du ja schon gesagt. Ist die Form und/oder die Größe des vorbeifallenden Objektes - bzw. dessen Abbildung im Bild - immer gleich oder ebenfalls veränderlich. Ändert sich die Entfernung zur Kamera - und damit die Abbildung - oder ist diese konstant ? cu Ha-Joe |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Erst mal vielen Dank für das Feedback.
Es fallen kontinuierlich mehrere Objekte gleichzeitig an der Kamera(USB 3.0) vorbei. Der Abstand zur Kamera ist immer gleich, auch die Beleuchtung und der 'Hintergrund' sind immer gleich. Es ist ein permanenter Produktstrom von Objekten im Bereich von ca. 0.1 mm bis 15 mm mit ca. 50 bis 100 Objekten pro Sekunde. Die Form ist meistens Oval. Eine 'mechanische' Ausrichtung der Objekte, z.B. mit einem Rillenblech ist aus Platzgründen nicht machbar und leider auch nicht sicher. Mit meiner Routine wird das Objekt quasi in jeder Himmelsrichtung gescannt. Die 'längste Pixelreihe', die der 'Längsachse' bei einem ovalen oder länglichen Objekt entsprechen müsste, wird gefunden und der erforderliche Drehwinkel wird ausgegeben. Die längs ausgerichteten (gedrehten) Objekte werden dann anhand ihrer Merkmale (z.B. Farbe, Farbvorkommen, Vergleich mit bekannten Mustern aus der Datenbank(z.B. Patternmatching) etc.) klassifiziert und deren Anteile Prozentual ausgegeben. Da die Erkennung schon viel Rechenpower benötigt, ist jede Geschwindigkeits-Optimierung sinnvoll. Die von mir vorgestellte Routine funktioniert, aber vielleicht gibt es, wie so oft, oder beim Programmieren immer, eine andere Möglichkeit. Ich habe trotz langer und häufiger Recherche nichts vergleichbares gefunden. Wer meine Routine nutzen möchte, muss die Winkel an seine Rotate-Procedure anpassen. |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Ich denke, üblicherweise wird so etwas mit einer Hauptachsentransformation gelöst. Oder, indem man eine Ellipse einpasst und deren große Halbachse bestimmt.
Das geht zum Beispiel mit Halcon direkt mit einem Methodenaufruf: https://www.mvtec.com/doc/halcon/181...egion_2nd.html Oder auch mit MATLABs image processing toolbox mit regionprops HAT habe ich mal selbst implementiert, den Aufwand würde ich mir aber heute nicht mehr machen. Falls es ein industrieller use case ist, einfach MATLAB kaufen, mit HG Kamera verbinden, 1 Tag Entwicklung, 2 Tage Test und fertig ist die Erkennung ;-) |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Danke für deine Antwort.
Das ist eine diskussionswürdige Vorlage. |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
..."freier Fall und 50 bis 100 Objekte pro Sekunde"...
mit einer normalen billigen 50Hz Kammera wird das kaum etwas werden. Zeit & Bild "sicher" wird es rechnerisch mit einer 200Bilder/sec Kamera... dann hast du 5msec pro Bild zum Vorverarbeiten("Erkennen","Markieren","Verfolgen") . Bei bis zu 100 erkannten Objekten, hast du dann "parallel" je 10msec Zeit deren Größe und Lage rechnerisch zu bestimmen... das funktioniert ist aber für einen StandardPC ohne Spezial-Hardware&Software ne sportliche Aufgabe. Ich würde kein Mathlab nehmen, sondern ne intelligente Kamera nehmen: https://www.vision-control.com/produ...8e1753a05152c4 |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Stimmt.
Wir sprechen von keiner billigen Kamera, sondern von einer mit Global Shutter und sehr hohen Frame-Raten. |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Eines vorab, ich habe schon zwei mal versucht einen langen Antwortpost zu erstellen und bin jedesmal rausgeflogen. Sprich mein Name/Passwort wurde erneut abgefragt und dann war der Post weg. Scheinbar wird man nun in kürzerer Zeit abgemeldet als vorher, deswegen teile ich meine Antwort nun auf.
An die Reihenfolge Deiner Beschreibung werde ich mich nicht halten, sondern in der Reihenfolge antworten die ich für sinnvoll halte. Da ich noch ein paar Fragen habe warte ich mit den zweiten Post noch ein wenig ? Zitat:
Oft werden solche Methoden auf S/W Bildern oder Graustufenbildern durchgeführt, was mir sagt das ein solches vermutlich zeitgleich existiert. Wenn das so ist, dann verwende dieses Graustufenbild mit Deiner Methode, was die Methode um ca. 2/3 beschleunigt. Zitat:
Must Du jedes Objekt klassifizieren oder könntest Du nicht klassfizierte Objekte "im Kreislauf" fahren? Hanst Du viele Klassen und damit eine sehr große Referenzdatenbank oder ist die Anzahl der Klassen überschaubar. cu Ha-Jö |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Delphi-Quellcode:
Der Zugriff mittels Canvas.Pixels ist in der Regel sehr langsam.
Procedure CheckPoints(X,Y: Integer; Canvas: TCanvas); StdCall;
var R, G, B:Byte; Color:TColor; begin {$R-} Color := Canvas.Pixels[X, Y]; R := GetRValue(Color); G := GetGValue(Color); B := GetBValue(Color); // prüfe, ob Pixelfarbe <> BackgroundTRGBFillColor if (R <> MainForm.BackgroundTRGBFillColor.r) and (G <> MainForm.BackgroundTRGBFillColor.g) and (B <> MainForm.BackgroundTRGBFillColor.b) then Inc(Distance); {$R+} end; Eine ausführliche Erklärung findest Du hier : https://wiki.delphigl.com/index.php/...ildbearbeitung cu Ha-Joe |
AW: Objekte zu ihrer Längsachse vertikal ausrichten
Danke für deine Mühe.
[ Zitat:
Die Objekte sind bereits isoliert. Die Bilder sind in Farbe, Umwandlung ist nat. kein Problem. Zitat:
Dadurch sollten die 'quer' fallenden Objekte von jetzt bis zu 20% auf Null gehen. Zitat:
Zitat:
Das Problem mit Canvas.Pixels ist bekannt, die Bilder der einzelnen Objekte sind aber relativ klein. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz