AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Objekte zu ihrer Längsachse vertikal ausrichten

Objekte zu ihrer Längsachse vertikal ausrichten

Ein Thema von newIndy · begonnen am 22. Mär 2019 · letzter Beitrag vom 25. Mär 2019
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von newIndy
newIndy

Registriert seit: 18. Dez 2018
29 Beiträge
 
Delphi XE3 Professional
 
#1

Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 22. Mär 2019, 20:20
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;
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
156 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 23. Mär 2019, 09:46
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.

Gibt es einen besseren Weg?
Besser in welchem Sinne. Robuster, exakter oder schneller ?

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
  Mit Zitat antworten Zitat
Benutzerbild von newIndy
newIndy

Registriert seit: 18. Dez 2018
29 Beiträge
 
Delphi XE3 Professional
 
#3

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 23. Mär 2019, 18:54
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.
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#4

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 23. Mär 2019, 22:34
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
  Mit Zitat antworten Zitat
Benutzerbild von newIndy
newIndy

Registriert seit: 18. Dez 2018
29 Beiträge
 
Delphi XE3 Professional
 
#5

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 24. Mär 2019, 07:47
Danke für deine Antwort.
Das ist eine diskussionswürdige Vorlage.
  Mit Zitat antworten Zitat
mensch72

Registriert seit: 6. Feb 2008
838 Beiträge
 
#6

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 24. Mär 2019, 07:55
..."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
  Mit Zitat antworten Zitat
Benutzerbild von newIndy
newIndy

Registriert seit: 18. Dez 2018
29 Beiträge
 
Delphi XE3 Professional
 
#7

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 24. Mär 2019, 08:11
Stimmt.
Wir sprechen von keiner billigen Kamera, sondern von einer mit Global Shutter und sehr hohen Frame-Raten.
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
156 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 24. Mär 2019, 19:14
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:
Da die Erkennung schon viel Rechenpower benötigt, ist jede Geschwindigkeits-Optimierung sinnvoll.
Deine Routine müsste eigentich auch funktionieren wenn es sich um ein Graustufenbild oder SW Bild handeln würde. Wenn ich Deine Beschreibung richtig gelesen habe, dann bezieht sich Deine Routine auf ein bereits isoliertes Objekt. Das bedeutet das vorher bereits eine Verarbeitung, sei es durch die Kamera, sei es durch Dich stattgefunden hat. Die Isolation der Objekte hat dann vermutlich mit Hilfe von Methoden wie beispielsweise dem Auffinden der größten verbundenen Komponente stattgefunden.

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:
Eine 'mechanische' Ausrichtung der Objekte, z.B. mit einem Rillenblech ist aus Platzgründen nicht machbar und leider auch nicht sicher.
Je mehr sich das Objekt während des Fallens oder davor mit der Längsachse parallel zur Blickrichtung der Kamera dreht, umso kürzer erscheint die tatsächliche Längsache und die "längste Achse" im Bild ist nicht zwangsläufig die längste tatsächliche Achse. Falls dieses Problem vorkommen kann brauchst Du eine zweite Kamera.

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ö
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
156 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 24. Mär 2019, 19:20
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;
Der Zugriff mittels Canvas.Pixels ist in der Regel sehr langsam.

Eine ausführliche Erklärung findest Du hier :

https://wiki.delphigl.com/index.php/...ildbearbeitung

cu Ha-Joe
  Mit Zitat antworten Zitat
Benutzerbild von newIndy
newIndy

Registriert seit: 18. Dez 2018
29 Beiträge
 
Delphi XE3 Professional
 
#10

AW: Objekte zu ihrer Längsachse vertikal ausrichten

  Alt 24. Mär 2019, 19:55
Danke für deine Mühe.

[
Zitat:
Deine Routine müsste eigentich auch funktionieren wenn es sich um ein Graustufenbild oder SW Bild handeln würde.
Das ist richtig, ich habe es auch in Erwägung gezogen, an der Stelle mit einem SW-Bild zu arbeiten.
Die Objekte sind bereits isoliert. Die Bilder sind in Farbe, Umwandlung ist nat. kein Problem.

Zitat:
Je mehr sich das Objekt während des Fallens oder davor mit der Längsachse parallel zur Blickrichtung der Kamera dreht, umso kürzer erscheint die tatsächliche Längsache und die "längste Achse" im Bild ist nicht zwangsläufig die längste tatsächliche Achse. Falls dieses Problem vorkommen kann brauchst Du eine zweite Kamera.
Auch wieder richtig. Dafür habe ich jetzt eine praktische Lösung. Der freie Fall wird durch eine schräg stehende 'Rutsche aufgelöst.
Dadurch sollten die 'quer' fallenden Objekte von jetzt bis zu 20% auf Null gehen.

Zitat:
Must Du jedes Objekt klassifizieren oder könntest Du nicht klassfizierte Objekte "im Kreislauf" fahren?
Jedes Objekt wird klassifiert, dann ist es weg.
Zitat:
Hanst Du viele Klassen und damit eine sehr große Referenzdatenbank oder ist die Anzahl der Klassen überschaubar.
Es gibt keine Klassenanzahlbegrenzung, es können in der Praxis aber ca. 5 bis 20 sein, je nach Produkt.

Das Problem mit Canvas.Pixels ist bekannt, die Bilder der einzelnen Objekte sind aber relativ klein.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:43 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