Sida 1 av 2

Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 02:27:11
av blueint
Om man förutsätter t.ex. en 640x480 8bpp bild från en bildsensor som läser ut linje för linje (CMOS?). Och att MCUn (AVR/PIC) har ~8 kByte flashminne och ~1 kByte RAM. Samt "nätverks" hastighet ~16 kbps. Finns det någon bildkomprimeringsalgoritm som man kan dra nytta av så att man får ner datamängden någorlunda utan att balansen mellan komprimering och nätverks-överföringshastighet tryter .. ?
Så att det inte tar längre tid att komprimera än att bara skicka datat rakt av ;)
Tänkte om någon testat något eller tänkt igenom problemställningen?

Jpeg kräver ~128 MByte minne, så det fungerar inte.
LZW verkar bygga på en 4096 positioners tabell. Men det kanske går att använda samma princip med en kortare tabell?
Huffman kodning bygger på träd, kanske för komplext?
RLE verkar något lovande.
Deflate kanske är ett alternativ?

Ev variationer kan vara 320x240 4bpp, mer eller mindre flash och ram. Samt nätverks hastighet uptill ~1 kbps - 1000 kbps. Beroende på vald hårdvaru kombination.

Edit: Förtydligande kompression vs överföring

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 02:47:53
av bearing
Sensorn kanske kan klockas långsamt, så att du slipper komprimera.

Jag föreslår wavelet med stark kvantifiering och sedan RLE av nollorna (blir många nollor). Kräver bara en rads minne, men ganska många loopar. Tveksam till om det går i realtid på en PIC vid närmare eftertanke.

Om sensorns klockfrekvens är högre än kortaste tiden för ett varv i en komprimeringsloop går det nog inte att komprimera. Så det blir inte så snabbt.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 02:52:46
av blueint
Det behöver inte vara riktigt realtid. Så tex. en bild varannan sekund är ok.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 03:08:13
av bearing
Eftersom att bilden inte får plats i bufferten måste komprimeringen ske i realtid.

Titta på Haar wavelet, den är enklast.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 09:32:22
av cyr
Går ju att koda olika delar från olika frames, om det är en någorlunda statisk bild (kommer se konstigt ut om något rör sig...)

JPEG kräver inte några 128MB, så länge du får plats med 8x8 pixlar och koden för DCT och huffman-kodning så går det nog att få in.
Är förmodligen ändå inte det bästa alternativet, men det borde kunna gå.

Sen finns det väl små kameramoduler med JPEG inbyggt ?

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 13:50:22
av blueint
Min tanke var att plocka ihop en mobiltelefonkamera + MCU och något enkelt Opencollector/RS485 nätverk så att man kan hålla koll på t.ex. spisen.

Jpeg modul = Komplicerande och svårare att få tag på.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 14:59:12
av AAVE
Får du inte rätt mycket brus i bilden med en sådan kamera? hur påverkar det komprimeringen?

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 15:07:35
av blueint
Brus är ju en risk, men mer påkostad bildsensor gör enheten kanske lite väl dyr.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 15:35:18
av AAVE
Jag tänkte mest på hur brus påverkar komprimeringen. RLE till exempel kommer inte alls att fungera medan JPG kanske klarar sig bättre tack vara kvantiseringen?

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 15:37:11
av bearing
Waveletkomprimering är genom sin natur brusreducerande. Det går ut på att medelsvärdesbilda och kvantisera.

Varför behöver du 640x480 i upplösning om du bara vill övervaka en spis?
Borde räcka med typ 160x120.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 15:58:32
av blueint
Vill ha lite detaljrikedom så man kan se när det kokar lagom.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 16:40:17
av blueint
Hur är Wavelet i jämförelse med Jpeg ..?
Det finns både processor begränssningar och effektivitets hänseende att tänka på i detta sammanhang.

Ev användning också för att kolla utomhus ;)

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 17:35:49
av bearing
Jag har labbat en del och jämfört JPEG2000 (wavelettransform av hela bilden) med vanlig JPEG (cosinustransform av 8x8-block). Mina intryck är att bilder med få detaljer blir visuellt bättre med JPEG2000 jämfört med JPEG vid samma komprimeringsgrad. Även extremt högt komprimerade bilder blir visuellt bättre med JPEG2000 jämfört med JPEG. Detaljrika bilder med medel till hög komprimeringsgrad blir visuellt bättre med vanlig JPEG. (Tycker jag.)


Gjorde några exempel.

Exempel 1: Spis med låg detaljrikedom och hög kompressionsgrad.
BMP, ca 800kb:
Bild
JPEG2000, ca 7kb; kompressionsgrad ca 110:1
Bild
JPEG, ca 7kb; kompressionsgrad ca 110:1
Bild

Exempel 2: Natur med hög detaljrikedom, hög kompressionsgrad.
BMP, ca 800kb:
Bild

JPEG2000, ca 8kb; kompressionsgrad ca 100:1
Bild

JPEG, ca 8kb; kompressionsgrad ca 100:1
Bild

Exempel 3: Natur med hög detaljrikedom, medel kompressionsgrad.
BMP, ca 800kb: (samma som ovan)
Bild

JPEG2000, ca 20kb; kompressionsgrad ca 40:1
Bild

JPEG, ca 20kb; kompressionsgrad ca 40:1
Bild


Som synes blir JPEG med kring 100:1 oacceptabelt blockigt. JPEG2000 blir istället väldigt suddigt vid 100:1, fast detaljer med hög kontrast, som t.ex. trädstam mot bakgrund suddas inte. Intressant är att i exempel 1 syns knappt skillnad mellan orginal och JPEG2000 110:1 eftersom att bilden från början har få skarpa ytor.

Vid 40:1 blir resultaten snarlika. Jag föredrar JPEG eftersom att jag tycker att den innehåller fler detaljer.


Tillägg: Vid granskning av bilderna på kort avstånd till skärmen syns tydlig skillnad mellan komprimerad och orginal. Vid normalt avstånd ser inte ögat alla detaljer i orginalet att skillnaden blir mindre.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 18:38:17
av bearing
Angående hur mycket processorkraft de tar vet jag inte, för jag har bara skrivit en Haar-wavelet-algoritm. Kan inte jämföra med JPEG. Jag har läst att wavelet kräver mer kraft, fast jag gissar att det är wavelets med flyttal. Haar är väldigt simpel.

I princip görs följande för varje rad på bilden:

Kod: Markera allt

#define width 640
int i,j;
int picture[width];
int average[width];
int diff[width];

j=0;
for (i=0; i<width; i+=2)
{
  average[j] = (picture[i] - picture[i+1]) / 2;
  diff[j] = picture[i] - picture[i+1];
  j++;
}
Sedan görs detta n gånger med average[] som indata istället för picture[] så att average[] får storleken width/2^^(n+1) och diff[] storleken width-width/2^^(n+1).

diff[] kommer innehålla många värden nära noll, vilka blir noll vid kvantiseringen och kan därför enkelt komprimeras med RLE.

Re: Bildkomprimering på AVR/PIC?

Postat: 9 april 2009, 19:13:42
av blueint
Blir not att jobba med 20 pixel i bredd i taget. Blir tight med 1 kByte ram-minne ;)

Sen tänkte jag kolla kastrullen ovanifrån, lite vid sidan så man slipper den värsta kondensen. För resterande kondens har jag en lösning ;)