Ansteuerung einer Wabcam mit Linux und Xuggler
(EN google-translate)
(PL google-translate)
Ansprechen von Geräteschnittstellen über Dateien in Linux
Beim Umgang mit der seriellen Schnittstelle wurde schon bemerkt, dass sich unter dem Betriebssystem Linux Hardwarekomponenten über Dateien ansprechen lassen.
Dieses Konzept bietet mehrere Vorteile:
|
Beispielsweise war die eingebaute serielle Schnittstelle als Datei ttyS0 im Verzeichnis /dev ansprechbar, also über /dev/ttyS0. Ein später hinzugefügter USB nach Seriell-Umsetzer hat dann den Eintrag ttyUSB gehabt. Bei der Programmentwicklung war bei einem Wechsel von der eingebauten seriellen Schnittstelle zum USB-Umsetzer nur eine Änderung der angesprochenen Datei nötig, also statt /dev/ttyS0 wurde /dev/ttyUSB0 angegeben.
Bild 0-1: /dev Verzeichnis vor und nach Anstecken des USB-Seriell-Umsetzers.
Test einer USB-Kamera
Xuggler bietet eine Programmier-Schnittstelle zur Ansteuerung einer USB-Kamera mit Linux. Dazu werden vorbereitete Java-Klassen aus einer Library verwendet, die in einem .jar-File gepackt sind. Darüber hinaus werden auch dynamisch hinzu geladene hardware nahe Libraries benötigt, die von diesen Java-Klassen benutzt werden, um die Kameraansteuerung realisieren zu können (.so-Dateien).
Die Java-Libraries von Xuggler (.jar-Dateien) sind in dem hier verwendeten Live-Linux-System unter /opt/xuggler/share/java/jars zu finden.
Die .so-Dateien finden sich unter /opt/xuggler/lib.
Als Testprogramm, das aufzeigt, wie man eine USB-Kamera ansprechen kann, steht unter /mnt-system/Z_Beispiele/javaxuggler_testwebcam das Programm DisplayWebcamVideo.java zur Verfügung.
Damit sich dieses Programm ohne weiteres kompilieren und starten läßt, müssen der Ort, an dem sich die Klassen aus den .jar-Dateien und die dynamisch hinzu geladenen Bibliotheken bekannt gemacht werden.
Dies wurde bereits in der Datei /etc/profile ergänzt. Wäre dies nicht geschehen, so könnte dies auch durch einige Konsolenbefehle bewirkt werden:
export XUGGLE_HOME=/opt/xuggler export LD_LIBRARY_PATH=/lib: export PATH=/bin:
Code 0-1: Vereinbarung des Homeverzeichnisses von Xuggler, Hinzufügen von /opt/xuggler/lib zum allgemeinen Bibliothekspfad, Hinzufügen von /opt/xuggler/bin zur Variable PATH.
Beim Kompilieren und Starten müssen der Ort der benötigten .jar-Dateien über die Classpath-Option (-cp) mit angegeben werden. Alternativ kann auch die Variable CLASSPATH zuvor entsprechend gesetzt werden.
Nach Einstecken der USB-Kamera liegt als neues Device /dev/video0 vor. Dementsprechend muß die Parameterübergabe bei DisplayWebcamVideo angepaßt werden.
javac -cp /opt/xuggler/share/java/jars/xuggle-xuggler.jar VideoImage.java javac -cp /opt/xuggler/share/java/jars/xuggle-xuggler.jar:. DisplayWebcamVideo.java java -cp /opt/xuggler/share/java/jars/xuggle-xuggler.jar:. DisplayWebcamVideo video4linux2 /dev/video0
Code 0-2: Kompilieren und Aufrufen des Testprogramms.
Programmanpassung / Re-Engineering
Wie kann dieses Testprogramm nun als Grundlage benutzt werden, eigene Java-Programme mit der Möglichkeit zu versehen, Bilder einer USB-Kamera zu verarbeiten?
Hierzu wird eine vereinfachte API entwickelt, die eine Brücke zwischen der Java-Standard-Edition und den speziellen Bibliotheksklassen darstellt.
Versuch einer Beschreibung des Vorgehens:
|
Testprogramme
import java.awt.image.BufferedImage; import java.awt.Color; public class TestWebcamKonsole { public static void main(String[] args) { BufferedImage bild = null; DisplayWebcamVideo.initKamera(); while(true) { bild = DisplayWebcamVideo.holeBild(); if(bild!=null) { int farbe_bildmitte = bild.getRGB(320,240); Color farbe_objekt = new Color(farbe_bildmitte); System.out.println(farbe_bildmitte +" Rotanteil:"+farbe_objekt.getRed() +" Gruenanteil:"+farbe_objekt.getGreen() +" Blauanteil:"+farbe_objekt.getBlue() ); } try { Thread.sleep(10); } catch(Exception e) { } } } }
Code 0-3: TestWebcamKonsole.java - Auslesen des mittleren Pixels und Ausgabe dessen RGB-Werte.
import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; public class TestWebcam extends Canvas implements Runnable { private BufferedImage bild = null; public TestWebcam() { JFrame fenster = new JFrame(); fenster.setBounds(10,10,680,520); fenster.getContentPane().add(this); fenster.setVisible(true); Thread thread = new Thread(this); thread.start(); } public void run() { DisplayWebcamVideo.initKamera(); while(true) { bild = DisplayWebcamVideo.holeBild(); repaint(); } } public void paint(Graphics g) { if(bild!=null) { g.drawImage(bild,0,0,Color.WHITE,this); } } public static void main(String[] args) { TestWebcam testwebcam = new TestWebcam(); } }
Code 0-4: TestWebcam.java - Darstellung des Kamerabildes in einem eigenen Fenster
import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; public class TestWebcamFilter extends Canvas implements Runnable { private BufferedImage bild = null; public TestWebcamFilter() { JFrame fenster = new JFrame(); fenster.setBounds(10,10,680,520); fenster.getContentPane().add(this); fenster.setVisible(true); Thread thread = new Thread(this); thread.start(); } public void schwellwertfilter(BufferedImage bild, int schwellwert) { for(int x=0;x<bild.getWidth();x++) { for(int y=0;y<bild.getHeight();y++) { int rgb = bild.getRGB(x,y); Color c = new Color(rgb); int summe = c.getRed() + c.getGreen() + c.getBlue(); summe/=3; if(summe>schwellwert) bild.setRGB(x,y,Color.WHITE.getRGB()); else bild.setRGB(x,y,Color.BLACK.getRGB()); } } } public void run() { DisplayWebcamVideo.initKamera(); while(true) { bild = DisplayWebcamVideo.holeBild(); schwellwertfilter(bild, 100); repaint(); } } public void paint(Graphics g) { if(bild!=null) { g.drawImage(bild,0,0,Color.WHITE,this); } } public static void main(String[] args) { TestWebcamFilter testwebcam = new TestWebcamFilter(); } }
Code 0-5: TestWebcamFilter.java - Sehr einfache aber wenig performante Umsetzung eines Schwellwertfilters (reine Testanwendung).