Viereck erstellen und Webcamtracking

ankmanu

Bekanntes Mitglied
Hi,

ich habe folgendes Projekt:
eine Webcam ist über einer Arbeitsfläche eines Roboters aufgebaut und macht ein Bild(von der Fläche). Nun wird dies gespeichert und soll schließlich ausgewertet werden. Bisher wird einfach nach einem gelben Pixel im Bild gesucht und dieser dann an ein anderes Unterprogramm weitergegeben, welches dann den Roboter so steuert, dass er dort zugreifen kann.
Da die Webcam aber nicht 100%-ig fest montiert ist, kann sie etwas wackeln. dadurch ändern sich natürlich auch die Koordinaten etc..
Ist es möglich quasi im Bild 4 "Trackpunkte" am Rande der Arbeitfläche festzulegen(die zum Beispiel grün sind und dadurch erkannt werden können) und dann ein Viereck aus diesen zu bilden?
Wenn ja, dann könnte man nämlich die Erkennung nur innerhalb des Vierecks aktivieren, oder?
Und wenn das geht, dann wie?

Hier mal mein bisheriges Programm, welches einfach den gelben Punkt sucht (das klapp super!):

Java:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class ImagePixelReader {
int x = 0;
int y = 0;

public ImagePixelReader() throws Exception {
System.out.println("Klasse ImagePixelReader gestartet");


        System.out.println("Einlesen des Bildes...");
        BufferedImage img = ImageIO.read(new File("c:/a.jpg"));                                 /**Das Webcambild wird geladen */
            
        for (int x = 0, maxX = img.getWidth(); x < maxX; x++) {                                 /** Die rgb-Werte aller Pixel werden ausgelesen */
            for (int y = 0, maxY = img.getHeight(); y < maxY; y++) {
        
        int rgb = img.getRGB(x, y);
        Color c = new Color(rgb);
        
        if(c.getRed()>200 && c.getRed()<=255 && c.getGreen()>100 && c.getGreen()<=255 && c.getBlue()>=0 && c.getBlue()<=70){
            System.out.println("Red: " + c.getRed());
            System.out.println("Green: " + c.getGreen());
            System.out.println("Blue: " + c.getBlue());
            Roboterpositionierung robpos = new Roboterpositionierung();
            robpos.main(x,y);
            
            }
        }}
         boolean success = (new File("c:/a.jpg")).delete();                                         /**File a.jpg wird gelöscht */
    if (!success) {
        System.out.println("Deletion of a.jpg failed!");                                     
    }
        
     try {
     Roboterpositionierung rp = new Roboterpositionierung ();}                                      /** nächste Klasse wird geladen */
     catch(Exception e){
                System.out.println("Klasse Roboterpositionierung konnte nicht geladen werden!!!");}
    }  
}
 /** ENDE */
Leider kann ich euch das Bild der Webcam nicht zeigen, weil man hier keine Grafiken einfügen kann (nur über URL).
Hier nochmal die Frage: Wie kann man
1) zwischen 4 (zum Beispiel grünen) Punkten ein Viereck bilden?
2) dann nur zwischen den Pixelwerten in diesem Viereck den gelben Punkt suchen?

Vielen Dank im Vorraus

manu
 
1) zwischen 4 (zum Beispiel grünen) Punkten ein Viereck bilden?
2) dann nur zwischen den Pixelwerten in diesem Viereck den gelben Punkt suchen?

1) Du hast ja schon den Code, einen Punkt zu finden. Wenn du also einen Punkt gefunden hast, speichere die Koordinaten und suche weiter. Damit hast du dann 4 xy-Koordinaten und damit dein Rechteck 🙂

2) Verstehe ich nicht so ganz. Du musst sowieso durch das komplette Bild iterieren, daher speichere die Koordinaten des gelben Punktes auch. Dann kannst du hinterher schauen ob
XgelberPunkt > XgrünerPunktLinksOben UND YgelberPunkt < YgrünerPunktLinksOben usw.

Komplizierter ist natürlich die Erkennung eines Punktes an sich, also: gehört Pixel xy zum Punkt?
 
Hi,

also danke erstmal, aber was ich bewirken will ist vollgendes:
Auch wenn die webcam etwas wackelt, soll der richtige x und y wert des gelben Pixels ausgegeben werden.
Deshalb wollte ich ein Viereck/Rechteck in den Aufnahmebereich der Kamera "malen" , welches eben z.B. durch vier Punkte in grüner Farbe gekennzeichnet ist. Dieses Viereck/Rechteck muss selbstverständlich kleiner als der Aufnahmebereich der Kamera sein, denn dann muss das Rechteck/Viereck nur "im Bild" sein und es wird der richtige Wert geliefert!

Hier nochmal der Aufbau:
Am Boden: Eine Arbeitsfläche, die an den Ecken mit grünen Punkten versehen ist sodass sie "getrackt" werden kann. Auf dieser steht irgendwo ein gelber Gegenstand.

drüber: Eine Webcam, welche jedoch (leider) etwas wackeln kann...
Diese muss dann erkennen, wo der Gegenstand steht, indem sie die 4 grünen Punkte sucht, diese zu einem Rechteck/Viereck verbindet und dadurch die Arbeitsfläche hat, egal wie verwackelt sie ist (hauptsache die 4 Punkte sind im Bild). Nun kann die webcam (ausgehend von den 4 punkten) doch immer die richtige position des Gegenstands feststellen, oder?

Doch wie dies in java geht, ist mir bisher noch ein Rätsel 🙁

Vielen Dank im Vorraus
manu
 
Ok, das Prinzip ist mir klar. Was mir nicht klar ist: wo genau hast du Probleme? Bei der Mathematik oder der Programmierung an sich?

Ein wirkliches Rechteck brauchst du nicht wenn ich dich richtig verstehe, sondern ein "virtuelles" damit du erkennen kannst, wo die wackelnde Kamera gerade filmt.
Überlege mal was du tun würdest, wenn du ein Rechteck hättest. Wahrscheinlich wirst du zu dem Schluss kommen dass du das gar nicht brauchst, sondern nur die Eckpunkte und die sind ja durch die grünen Punkte sowieso schon gegeben.

Anders ausgedrückt: was du brauchst ist ein Koordinatensystem. Der Abstand zwischen den grünen Punkten und deren absolute Positionen sind definiert und daraus lässt sich dann die absolute Position des gelben Punktes berechnen.
 
Moin,

Gelber Punkt

  1. Farbfilter über das Bild legen
    • RGB Werte vergleichen - wo ((R&G)&!B) ist Gelb
    • Formel beachten sonst bekommst Du auch die Grünen Punkte
    • damit kannst Du ein schönes Binärbild erstellen
    • Gelb wird 1 und Rest ist 0
  2. über alle Punkte die X und Y Koordinaten addieren
  3. die X und Y Koordinaten durch die Anzahl der gelben Punkte dividieren
  4. damit hast Du den Schwerpunkt (Mitte) des gelben Punktes (Du errechnest nur den ersten vorkommenden - oben + links)

grüne Punkte
  1. Farbfilter über das Bild legen
    • RGB Werte vergleichen - wo (!R&G&!B) ist Grün
    • Binärbild erstellen - wie bei Gelb
  2. nun hast Du 4 Kleckse - die erreichst Du durch Segmentierung [click] des Bildes
  3. nach der Segmentierung hast Du 4 Rechtecke - die kannst Du jeweils als ein neues Bild betrachten
  4. in den Rechtecken berechnest Du wieder den Schwerpunkt
  5. dann hast Du 4 Schwerpunkte - Rest sollte nicht mehr so schwer sein

hand, mogel
 
Hi,

danke, an genau so etwas habe ich gedacht, doch mir fehlts an den Kenntnissen in der Programmierung...
Ich habe mit Müh und Not die Suche nach dem gelben punkt abgeschlossen, wie kann ich das dann realisieren?
Könnt ihr mir da ein bisschen helfen?

Vielen Dank im Vorraus

manu
 
Moin,

korregiere erstmal Deine Suche nach dem Gelben Punkt besser

Java:
private int [][] getBinaryPicture(Image img, boolean red, boolean green, boolean blue)
{
    int picture [][];
    
    // TODO

    return picture;
}

wenn Du es gleich "richtig" machst, fällt Dir die Suche nach den Grünen Punkten auf die Füße (mehr oder weniger)

Java:
private int [][] getBinaryPictureYellow(Image img)
{
    return getBinaryPicture(img, true, true, false);
}
private int [][] getBinaryPictureGreen(Image)
{
    // TODO
}

und dann fehlt noch die Berechnung des Schwerpunktes

Java:
private Point getCenter(int [][] picture)
{
    int sumX = 0; // Summer aller X-Koordinaten
    int sumY = 0; // Summer aller Y-Koordinaten
    int count = 0; // Anzahl der Pixel

    // TODO

    return new Point(sumX / count, sumY / count);
}

im Übrigen macht es sich besser das Bild in ein Array zu Wandeln ... ich weis nicht was Java intern bei einem getPixel() macht ... es dürfte aber wesentlich mehr Rechenzeit verbrannt werden als wenn Du in einem Array auf einen Wert zugreifst (unter .NET auf jedenfall 😀) ... wobei ich jetzt nicht weis wieviel Zeit Du pro Bild hast

außerdem sucht man nach Farben über HSI - aber das willst Du im Moment nicht

hand, mogel
 

Neue Themen


Zurück
Oben