Forum: Mikrocontroller und Digitale Elektronik JPEG-Umwandlung mit AVR


von Marco Haufe (Gast)


Lesenswert?

Hallo Leute
Bin heute zum erstenmal auf der mikrokontroller.net Seite...
Allerdings bin ich sehr positive beeindruckt bzgl. dem know-how in den
Beiträgen.
Ich habe auch ein kleines problem. Vielleicht hat ja jemand damit schon
mal Erfahrung gesammelt :
Ich habe einen AVR-Mega128 mit einem CCD-Chip 128x96Pixel in b/w
verheiratet. Auslesen und in einem passenden VB6-Programm darstellen
klappt prima.
Aber wie kann ich aus dem Grauwert einer jeden Pixel-Zelle letztlich
ein JPEG machen, und dieses z.B. im Explorer anzeigen zu lassen.
Also im Klartext --> der AVR soll das Graustufenbild in ein JEPG
wandeln, wie es z.B. jede Digicam macht.
Habe schon in diverser Literatur gestöbert, scheint mir aber alles sehr
komplex, und eine Vorstellung, wie ich das selber programmieren kann,
habe ich daher auch noch nicht. Weiß einer von Euch weiter ?
Viele Grüße
Marco

von Jörg (Gast)


Lesenswert?

Hi! Ich muß mal raussuchen, welche logischen Schritte in der
JPEG-Kopression stecken.
Kanst Du mir erklären, wie Du den ccd-chip an den Atmel angeknotet
hast?

Gruß
Jörg

von Marco Haufe (Gast)


Lesenswert?

Hi Jörg,
hört sich ja schon vielversprechend an !
Prinzipiell ganz einfach, da dieser Chip schon
einen digitalen Ausgang hat. Aber ich nutze noch einen
DualportRAM, wegen der Geschwindigkeit, die leider
bei dem CCD-Chip nicht zu verachten ist.
Ich suche Dir die Typbezeichnungen heute Abend mal raus...
VG Marco

von Jörg (Gast)


Lesenswert?

So.. hier habe ich ine sehr detailierte Ausarbeitung des JPEG-Verfahrens
gefunden!

Grundsätzlich kann man diese vier Schritte nennen:

1. RGB -> YCbCr-Wandling (Farbverteilungsraster wird ab hier gröber)

2. Discrete Cosinus Transformation (auf 8x8 Pixel-Blöcke)

3. quantisierung der Koeffizienten
   -> große Häufigkeit kleiner Werte und Null-Koeffizienten
     (Durch Quantisierungstabellen, kann gezielt der Kompressionsfaktor
gesteuert werden)


4. "Zick-Zack-Scanning" führt zur bevorzugten Nullfolge

5. Run-Level-Codierung der Nullen
   (viele Nullen führen zu kleiner Datenmenge)

6. Huffmann Codierung der Koeffizienten, die ungleich Null sind.
   (Werte mit hoher Wahrscheinlichkeit bekommen kurzes Codewort,
   und Werte niedriger Wahrscheinlichkeit erhalten ein längeres
Codewort.)

Die Details entnimmst Du bitte dieser Ausarbeitung:
http://www.mathematik.de/spurendermathematik/spudema_beitraege/beitraege/rooch/kap04.html

von Max (Gast)


Lesenswert?

Hallo

Währe es nicht einfacher die JPEG komprimierung dem PC zu überlassen?
ich min in VB solte das kein problem sein.

von Jörg (Gast)


Lesenswert?

Hiho Max!
Sicher aber dann kann man ja auch gleich ne USB-Webcam für 20 Euronen
am PC anklemmen.

Ich denke Marco geht es genau wie mir darum, wie man sowas selber lösen
kann, um es evtl. auch mal in nem Embedded System  ganz ohne PC
einzusetzen.

von Marco Haufe (Gast)


Lesenswert?

Hallo Jörg, hallo Max
Ich danke Euch für Euren Input !

Jörg : -->
der Dualport-RAM ist ein Averlogic AL422B, der CCD ein Omnivision
OV5017. Der CCD muß zuerst initialisiert werden. Ganz normal via 8-Bit
Datenbus mit CE und Tristate. Im Übertragungsmode schaufelt der CCD die
Daten pixelweise in den DualportRAM. Der CCD hat dafür extra
Steuerleitungen, der DualportRAM ist einer mit zwei internen,
voneiander unabhängige Adresszähler mit Takt und Reset.
Dieser Vorgang geht beinahe von selbst, aber sehr schnell. Zu schnell
für den AVR. Deshalb der DualportRAM. Der AVR holt sich die Daten von
diesem ab.

Max : -->
Prinzipiell hast Du Recht. Aber, ich bin ein echtes Spielkind, wenn ich
mal Zeit habe. Wenn ich mir was in den Kopf gesetzt habe, ziehe ich das
durch bis zum erbrechen oder bis ich eine eventuelle sinnlosigkeit
einsehe.
In meiner sehr knapp bemessenen Freizeit tüftle ich gern herum. Meine
liebsten Spielzeuge sind zur Zeit ein AVR in Kombination mit Hardware
TCP-IP-Stack, mein GSM/GPRS Funkmodul, und der CCD-Chip. Nun wuchs die
Idee :
Alle Welt redet von Netzwerk, bla...
Aber wie komme ich zu einem Netzwerk (Internetzugang, wenn meine
Embedded-Applikation auf einer grünen Wiese steht, und von Akku /
Solarzellen gespeist wird ?
OK, Daten usw. kein Problem die zu übertragen, aber genial wäre es wenn
es auch Bilder sind, also eine Art Web-Cam/Server auf der Wiese,
wo ich mich ganz ohne Aufwand mit einem IE verbinden kann.
Hat erstmal keine konkrete Anwendung hinter, aber ist doch schön, wenn
man weiß, man könnte soetwas oder auch ähnlich realiseren
Ist ja nur so eine Idee, dient ja auch der Weiterbildung und
Selbstbefriedugung

Viele Grüße
Marco

von Jörg (Gast)


Lesenswert?

Hey Marco...

ich hab seit Weihnachten auch ein Ethernet-AVR-Modul.. hab aber leider
kaum Doku dabei....schimpft sich MicroWebserver von Achatz

Welchen Hast Du denn, hast Du da irgendwelche Doku-Files drüber, oder
Tipps für mich?
Da ist nämlich weder die Firmware, also der Quellcode des Atmels noch
die Kommunikation zwischen Webpage und Atmel erklärt..darin werkelt ein
AT90S8515.
Leider finde ich da keinen richtigen Einstieg wie ich ein evtl. Projekt
anzufngen habe.

Gruß
Jörg

von Marco Haufe (Gast)


Lesenswert?

Hallo Jörg
so spät noch so fleißig !
Habe von MCSELEC.COM das EASY-TCPIP-Board.
Ein Haufen Doku, Besipiele usw. gehören dazu.
Das beste ist, BASCOM-AVR, die Entwicklungsumgebeung,
ist genial (obwohl einige das belächeln), ich habe nen guten
persönlichen Draht zum SW-Entwickler, und habe das BOard HW-mäßig
designed...

Viele Grüße
Marco

von Sven (Gast)


Lesenswert?

Hallo
schau doch mal bei Round Solutions vorbei deren GM 862 GPRS GSM Modul
verfügt jetzt auch über eine Kamera Schnittstelle mit denen du Bilder
schießen und per GSM z.b auf nen Webserver übertragen kannst.
Ich selbst besitze die ältere Version ohne Kamera Anbindung und muß
sagen, das diese Module nicht nur relativ preiswert sind, sondern auch
sehr zuverlässig arbeiten.

http://www.roundsolutions.de/de_overview.htm

Das erwähnte GSM Modul heißt: GM 862 PCS

Viele Grüße

Sven

von Marco Haufe (Gast)


Lesenswert?

Danke Sven,
ist ein guter Tip. Die Website sieht interessant aus (besonders
preislich),wobei ich aber bei dem Modul bleibe, welches ich verwende,
sont komme ich ja nie zu Potte.
Viele Grüße
Marco

von Hagen (Gast)


Lesenswert?

VIelleicht wäre es als erster Schritt einfacher sich auf GIF oder PNG zu
konzentrieren. Die WEB Browser haben mit diesen Formaten wenig
Probleme, und die Programmierung dieser Formate ist erheblich
einfacher. Ich selber habe schon auf dem PC eine Jpeg Dekomprimierung
gecodet die war schon schwer genug. Die Komprimierung ist nochmals
komplizierter.

Gruß Hagen

von Marco Haufe (Gast)


Lesenswert?

Hallo Hagen
PNG höre ich zum ersten mal.
Aber mit dem GIF hast Du vielleicht Recht.
o.k. wie macht man denn aus einem Graustufenbild ein GIF ?
Viele Grüße
Marco

von Jörg (Gast)


Lesenswert?

Hi!

Also die GifKompression ist in der Tat einfacher zu realiosieren. und
da die Kamera sowieso nur Graustufen macht. kommt man auch ganz gut mit
256-Farben aus. Obwohl die Kompression ja bei homogenen Farbflächen
(eigentlich Zeilen) besser komprimiert, als wenn es z.B. Photos sind.

Hier das Prinzip:

http://www.peliworks.de/design/formateold/gif_kompress.html
http://goethe.ira.uka.de/seminare/rftk/gif/


Man kann das sogar einfach mit leichten BEispielen auf dem Papier
durchspielen.. komprimieren.. dekomprimieren.. udn es kommt tatsächlich
das gleiche Bild raus.

Viel Spaß

von Jörg Wunsch (Gast)


Lesenswert?

Für JPEG gibt's ja auch eine Opensource-Bibliothek, die komplett in C
geschrieben ist.  Allerdings sind das einige 10000 Zeilen Quellcode...

Dennoch, einen Versuch wäre es sicher wert, diese mal auf dem AVR zu
compilieren.  Soweit ich sehen kann, werden die Datentypen, die eine
bestimmte Bitlänge brauchen, sauber deklariert.

Auf einem ATmega128 könnte das Ergebnis schon benutzbar sein.

von Marco Haufe (Gast)


Lesenswert?

Danke für die Infos !
Werde mich wohl für die GIF-Variante entscheiden, diese scheint
wirklich einfacher zu sein...
Marco

von Jörg Wunsch (Gast)


Lesenswert?

Na, dann kauf Dir schon mal das LZW-Patent. :-)

GIF bzw. PNG komprimieren gut bei wenigen Farben (typische
Zeichungen).  JPEG komprimiert bei Fotos dagegen gut.  Mir dünkt, Du
hast einen typischen Fall von Fotos :), insofern würde ich JPEG noch
nicht völlig zu den Akten legen an Deiner Stelle.

Du mußt ja gottseidank die Algorithmen, die die Informatiker dafür
schon aufgeschrieben haben, nicht komplett neu erfinden.

von Marco Haufe (Gast)


Lesenswert?

Hallo Jörg,
ich muß schon zugeben, das JPEG rein von der Anwendung vielleicht doch
besser wäre, jedoch war ich ein wenig über den dafür nötigen
Aufwand erstaunt oder besser, erschreckt.
Was ich möchte ist eigentlich 'nur' ein Bild auf ein Webserver via
ftp schaufeln, welches ein normaler Browser anzeigen kann....

Was mit LZW ist, muß ich noch schlaumachen.

Generell bin ich sehr postiv überrascht, welchen In und Output ein
solches Forum innerhalb weniger Tage bringen kann !
VG Marco

von Jörg (Gast)


Lesenswert?


von Hagen (Gast)


Lesenswert?

Übrigens TIFF wäre auch noch eine Variante. Vorteile beim TIFF wären
einfachere Komprimierung, höhere Farbtiefe = Echtfarben, und ganz
wichtig ein Teil der Datenstrukturen kann beim Jpeg Format wieder
verwendet werden. Meine DigiCam macht Jpeg und eben TIFF.
Das LZW-Patent kümmert dich nicht mehr, bis du deine Lib fertig hast
gibts das patent nicht mehr.

Ich vermute mal das der CCD sowieso kein so besonders gutes Kontrast-
Verhalten hat. D.h. mehr als 256 Graustufen benötigst du nicht, da das
menschliche Auge kaum mehr Graustufen wahrnehmen kann. Somit würdest du
mit einem 256 Graustufen GIF wesentlich kompaktere Dateigrößen bekommen
als mit einem 4Mio Echtfarben Jpeg. Jpegs mit nur 256 Farben wiederum
tendieren dazu bei der Kompression zu starke Farbabstraktionen durch
zuführen, D.h. es entstehen große Flächen mit gelicher Farbe. Jpeg
komprimiert immer dann gut wenn man Echtfarb Bilder hoch komprimeiren
will.


Gruß Hagen

von Hagen (Gast)


Lesenswert?

Das einfachste Verfahren wären die komprimierten BMP's. Diese nutzen
RLE = Run Lenght Encoding. Normalerweise sollte diese Kodierung mit 10
Zeilen Source erledigt sein. Das Dateiformat von BMP's ist ebenfalls
sehr einfach. Ich würde damit anfangen, wenn ich demnächst selber in
die Welt der MCU Programmierung einsteige.

Allerdings, RLE Kodierung komprimiert nicht so stark wie GIF's LZW.

Gruß Hagen

von Jörg Wunsch (Gast)


Lesenswert?

> Ich vermute mal das der CCD sowieso kein so besonders gutes
> Kontrast- Verhalten hat. D.h. mehr als 256 Graustufen benötigst du
> nicht, da das menschliche Auge kaum mehr Graustufen wahrnehmen
> kann. Somit würdest du mit einem 256 Graustufen GIF wesentlich
> kompaktere Dateigrößen bekommen als mit einem 4Mio Echtfarben
> Jpeg.

Du irrst.  Ich habe mal spaßeshalber das Bild hier:

http://www.interface-business.de/~j/fabian/schaffell.jpg

rausgekramt.  Hier die Ergebnisse:

% ls -l sch*
-rw-rw-r--  1 j  wheel  137366 Feb 11 14:56 schaffell.gif
-rw-rw-r--  1 j  wheel   20978 Feb 11 14:56 schaffell.jpg
-rw-rw-r--  1 j  wheel   88304 Feb 11 14:56 schaffell.png
-rw-r--r--  1 j  wheel  175270 Feb 11 14:55 schaffell.pnm

Das Original ist das PNM File, ein Graustufen-Scan mit 256 Graustufen.
Der ist erwartungsgemäß am größten.

Das JPEG ist mit der gängigen 75 % Komprimierung gemacht und
entspricht im Wesentlich dem Bild auf der Webseite oben (auch wenn das
wohl bißchen heller ist).  Es sind noch keine nennenswerten
JPEG-Artefakten zu sehen.

Das PNG ist mit Kompressionsfaktor 6 abgespeichert, wobei mir das
Kompressionsverfahren gerade nicht bewußt ist.

Das GIF hat eine miserable Kompressionsrate, da LZW-Kompression halt
für Fotos denkbar ungeeignet ist.

(RLE-BMP kann ich nicht abspeichern.)

von formtapez (Gast)


Lesenswert?

Hallo !

Hier gibt es ein paar Quelltexte zur JPEG-Kompression.
Vielleicht hilft es Dir ein wenig weiter.

http://www.faqs.org/faqs/jpeg-faq/part2/index.html

MfG
formtapez

von Khani (Gast)


Lesenswert?

Hallo Leutz,

Punkt 1: Nicht jedes Kompressionsverfahren ist für jede Art Bild
optimal ! So ist beispielsweise JPG optimal für Scans und
DigiCam-Bilder, sprich "natürliche" Bilder. GIF und RLE (bei BMP)
sind dagegen besser für künstliche Bilder geeignet.
Punkt 2: JPG ist ein verlustbehaftetes Kompressionsverfahren, GIF und
RLE erhalten die komplette Information.
Punkt 3: Falls jemand glaubt GIF wäre ein leicht zu implementierendes
Verfahren, der hat bisher nur Beispiele codiert und decodiert - wenn
man da mal ein "richtiges" Bild drauf loslässt, dann muss man schon
ein wenig in die Trickkiste greifen, wenn man das ohne Speichermassen
und CPU-Monster in annehmbarer Zeit hinbekommen will (beides auf dem
µController eher Mangelware).

Vielleicht kann man da zum Teil ja auf spezialisierte Hardware
zurückgreifen. Ich kann mir schon vorstellen, dass man bei JPG was
herausholen kann, da solche Pixel-Transformationen doch ganz gut mit
irgendwelchen kleinen Rechenzwergen durchführbar sind (DSPs ? - da
gibt's auch kleine - nicht diese Riesenmonster)

MfG, Khani

von Jörg Wunsch (Gast)


Lesenswert?

Ein ATmega128 sollte DSPig genug sein dafür...

von Marco Haufe (Gast)


Lesenswert?

Damit ihr mich nicht falsch versteht,
es ging mir darum auf einfachen Weg ein Graustufenbild,
via ATMEGA128 in ein Bildformat zu konvertieren, welches
dann im Webbrowser, z.B. IE ansehbar ist....
Viele Grüße Marco

von Jörg Wunsch (Gast)


Lesenswert?

Meiner Meinung nach kannst Du ein PNG auch unkomprimiert aufbauen.
Das müßte dann der einfachste Weg sein.  GIF gibt's nicht
unkomprimiert, dort mußt Du immer erst den LZW-Krempel durchlaufen.

von Hagen (Gast)


Lesenswert?

Na dann ist das BMP Format am einfachsten, es muß ja nicht komprimiert
werden ! Angenommen der CCD liefert 320x200 Pixel in 8 Bit Graustufen,
dann würde die BMP ca. 64Kb groß sein. Dazu müsstest du nur die von der
CCD geliefereten Daten 1 zu 1 mit einem BMP-Header versehen, fertig.
Zusätzliche komprimierungen werden erstmal nicht nötig. Diese Bilder
können sofort durch die Browser angezeigt werden. Allerdings, ein
solches Bild sollte mit JPeg eben nur noch 8-16 Kb groß sein, im
Vergleich zu 64Kb. Vom Aufwand her ist es aber für dich der einfachste
Weg.

Es stimmt schon das Jpeg gerade bei Bildern die beste Komprimierung
liefert im Vergleich zu GIF. Aber die Komprimierungen die ich als
Source gesehen habe kommen nicht unter 10.000 Zeilen C Source aus. Sie
benutzen zudem meistens Fließkomma Arithmetik. Die GIF Komprimierung
basiert auf einfacher Integer Arithmetik und ist im Vergleich sehr
simpel. Man muß ja nicht alle möglichen GIF Formate implementieren,
sondern nur das passende 256 Graustufen Format.


Gruß hagen

von Jörg (Gast)


Lesenswert?

Ich denke auch, daß .gif hier das beste Aufwands/Leistungs-Verhältnis
bietet!

von Jörg Wunsch (Gast)


Lesenswert?

BMP ist Ineternet Explorer only.  Andere Browser (besonders in der
Welt außerhalb Windows) können das nicht (direkt) anzeigen.

Je nachdem, ob Marco hier portabel sein möchte, kann das ein Problem
sein.  Ein nichtkomprimiertes PNG sollte auch nicht aufwendiger zu
erzeugen sein (das Prinzip bleibt ja: Header davon, dann zeilenweise
raussenden), und es ist portabel.

von Roman (Gast)


Lesenswert?

mich würde der CCD-Chip und die verheiratung interessieren.

Kannst du mir genauere INfos geben?

von Hagen (Gast)


Lesenswert?

Mit dem PNG Format kenne ich mich nicht aus. Wenn wie Jörg sagt der PNG
Header eines unkomprimierten PNG's es zulässt als erstes vollständig
erzeugt zu werden, und die anschließenden Daten 1 zu 1 üebrmittelt
werden können, dann ist unkomprimiertes PNG genauso simpel wie BMP. Ich
bin davon ausgegangen das PNG gleich-kompliziert wie Jpeg ist, und JPeg
ist Chunk basierend bei dem man Rückbezüge erst nach dem
Umwandeln/übertragen der Daten berechnen kann. Das bedeutet dann
nämlich das alle Daten im Speicher gehalten, umgerechnet weren müssen,
die Header berechnet werden, und erst dann alles übertragen wird.

Beim unkomprimierten BMP, und PNG nach Jörgs Aussage, wäre dies nicht
der Fall. Man kann beim BMP den Header sofort vollständig erzeugen, da
die Auflösung und Pixelformat bekannt sind.

Beim GIF wird es so sein das die Komprimierung beim LZW um so besser
wird je mehr SRAM zur Verfügung steht. Der LZW-Ring-Buffer ist glaube
ich 256 Bytes groß. Die Verarbeitung der Daten kann aber sequentiell
erfolgen, d.h. Auslesen eines Bytes, rein in LZW, komprimiert und
Ausgabe des eventuell nächsten Bytes. Dies wird mit Jpeg garantiert
nicht möglich sein, da Jpeg Komprimierung Interpolationen über ganze
Blöcke von Pixeln durchführt.

Gruß hagen

von Jörg Wunsch (Gast)


Lesenswert?

Ja, wenn ich mir ein simples unkoprimiertes PNG-File mit meinem
PGM-File vergleiche (PGM ist eine simple Bytefolge, ein Byte pro
Pixel, Grauwerte 0..255), dann erkenne ich nach dem PNG-Header die
Bytefolge 1:1.  Was nicht sofort offensichtlich ist, aber beim Lesen
von http://www.libpng.org/pub/png klar wird ist, daß es auch noch
einen Trailer gibt, eine Dateiendekennung.  Sollte aber auch kein
Problem sein.  PNG wird in sogenannten Chunks aufgebaut, von denen es
mindestens IHDR (image header, hier steht die Bildgröße, Bittiefe,
Angaben zur Kompression etc.), IDAT (image data) und IEND (image end)
geben muß.  Außerdem können noch Kommentare, ein Zeitstempel und
andere Dinge untergebracht werden.

Das Aufwendigste dürfte die Berechnung der Chunk-CRCs sein, aber dafür
gibt es ja bereits Beispiele in inline asm.

Für JPEG: wenn ich mich nicht irre, rechnet JPEG in 8x8 Quadraten.
Dann muß man aber auch nur 8 aufeinanderfolgende Scanlines
zwischenspeichern, danach kann man diese weiterverarbeiten lassen.

von Hagen (Gast)


Lesenswert?

>Für JPEG: wenn ich mich nicht irre, rechnet JPEG in 8x8 Quadraten.
>Dann muß man aber auch nur 8 aufeinanderfolgende Scanlines
>zwischenspeichern, danach kann man diese weiterver

Das ist richtig, aber zeigt schon das Problem. Man muß dann nämlich, um
Speicher-/Takteffizient zu sein, diese 8 Scanlines als Ring Buffer
organisieren. Somit würde man nur jeweils 1 Scanline im Ring-Buffer
nachladen. Übrig bleibt dennoch das Problem das die Farbtabellen erst
nachdem die Imagedaten berechnet wurden, erzeugen kann. Die
Farbtabellen selber müssen aber in der Datei noch vor den Imagedaten
liegen. Alleine dieser Punkt bedingt das man die Imagedaten
komprimieren muß, deren Resultat zwischenspeichern muß, und erst danach
die Datei erzeugen kann.

Ich halte PNG für besser, da man einiges an Hardware sparen kann, wenn
man so direkt Byte für Byte vom CCD abholen kann, CRC berechnen, und
Byte gleich weiter senden kann.

Gruß Hagen

von Marco Haufe (Gast)


Lesenswert?

Hallo Jörg,
wenn Du noch an der Schaltung noch Interesse haben solltest,
sage Bescheid. bin gerade am Layouten...
Gruß Marco

von Jörg (Gast)


Lesenswert?

Hallo Marco!

Ja, ich bin sehr daran interessiert!
Das ist ja toll!

Gruß Jörg

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.