Vraag:
Lossless compressietechniek voor digitale signalen in een embedded systeem
toasty
2020-07-29 02:24:07 UTC
view on stackexchange narkive permalink

Hier is het scenario:

Ik heb een embedded systeem waarbij een ADC elke 2 seconden een 16-bits potentiostaat -monster registreert.Het systeem blijft wekenlang gegevens vastleggen, waardoor geheugengebruik een punt van zorg is.

Hoe kan ik, in plaats van 16 bits opslagruimte te gebruiken voor elk van de miljoenen samples, het signaal zonder verlies comprimeren terwijl het wordt gelogd?Idealiter zou ik het signaal willen opdelen in gecomprimeerde segmenten van 15 minuten.Ik weet zeker dat hier een standaard voor bestaat, maar ik kan die niet vinden.

Als het helpt, heeft het signaal meestal zeer lage delta's tussen samples (lage frequentie).

Slaat u onbewerkte ADC-waarden of geconverteerde waarden op (drijvende komma met enkele / dubbele precisie)?Tijdstempel?Slaat u ze op in flash of RAM?
Momenteel buffeer ik 450 onbewerkte samples in RAM en sla ze alle 450 op om te flitsen met een tijdstempel.
@toasty Vertel ons veel meer details over die voorbeelden.Echt nuttige ideeën over compressie vereisen een zeer gedetailleerd begrip van waar u mee te maken hebt.Als dit bijvoorbeeld gegevens zijn van een exponentieel vervalgebeurtenis met een bepaald soort ruis, hebben bepaalde ideeën de voorkeur boven andere.Zo is het.Hoe meer we weten, hoe beter het antwoord dat u kunt krijgen.
Het is een potentiostaat.
en moet meerdere analyten ondersteunen
Ik zou sterk in de verleiding komen om een SD-kaart te gebruiken (micro of niet).De kleinste die u kunt kopen is ongeveer 16G of 32G, wat ongeveer 544 of 1088 jaar aan samples kan bevatten @ 2 bytes 0,5 sps, de overhead van het bestandssysteem niet meegerekend.Als u een compatibel bestandssysteem implementeert, kan het voor analyse naar een pc worden gekopieerd.
SD-kaart valt buiten het bereik van het project :)
Realiteitscontrole: "een SD-kaart gebruiken" valt buiten het bereik van uw project, maar "een nieuwe, op maat gemaakte techniek ontwikkelen voor verliesloze compressie van gegevens" is dat niet ???Je realiseert je dat, als er * enige waarde * aan je tijd wordt gehecht, de economie hier volledig achterstevoren is.Tenzij dit een puur passieproject is, doe het dan niet.
Heb je eigenlijk een nauwkeurigheid van 16 bits?Als de onderste vier bits slechts willekeurige ruis zijn, heeft het geen zin om ze te loggen.
U kunt een SD-kaart en -lezer krijgen voor <$ 20 die meerdere gigabytes aan gegevens kan bevatten.Als je Arduino gebruikt, zijn er zelfs bibliotheken die al het protocol en het bestandssysteem voor je doen, dus je kunt het gewoon aansluiten en het vertellen dat het gegevens moet schrijven.
Welkom!"Embedded" kan zo'n breed scala aan mogelijkheden betekenen ... Ik neem aan dat dit systeem geen Linux of een gelijkwaardig besturingssysteem kan draaien dat zip, lzma, enz. Als een eenvoudig antwoord zou geven.Als het gebruik van een SD-kaart niet mogelijk is, zou het helpen als we wat meer zouden weten over de mogelijkheden van uw systeem.Het ontwikkelen van een dergelijke oplossing is een afweging, maar we kunnen niet veel helpen als we niet weten wat u probeert te balanceren.Batterijduur?Kosten?Fysieke afmetingen?Hoeveel monsters moet u opslaan?
Het fysieke en elektrische ontwerp ligt vast en kan dus niet worden uitgebreid.Het is een systeem op batterijen met een microcontroller die een bare-metal programma uitvoert.Als ik hulp nodig had bij het ontwerpen van het systeem en het kiezen van componenten, had ik dat in plaats daarvan gevraagd.Ik was benieuwd welke oplossingen voor signaalcompressie er bestonden en de antwoorden waren tot nu toe passend en zeer nuttig.
Lossless-compressie is statistische modellering en u hebt niet veel van een model geleverd.Van wat je ons hebt verteld, kun je niet veel beter doen dan Huffman die de delta's codeert.Hoe dan ook, een potentiostaat lijkt een behoorlijk luidruchtig apparaat te zijn, en je kunt ruis niet comprimeren, dus ik stel me voor dat je op zijn best 2: 1 compressie krijgt.
@toasty "Het mooie van normen is dat er zoveel zijn om uit te kiezen."
Zes antwoorden:
Dave Tweed
2020-07-29 03:47:03 UTC
view on stackexchange narkive permalink

Bij compressie gaat het erom de overtolligheden in de gegevens te vinden en ze te verwijderen. Aangezien u ons niet veel over uw feitelijke datasets lijkt te kunnen vertellen, zal dit antwoord erg algemeen moeten zijn.

Ik begrijp dat "potentiostat" -gegevens continu zijn, in het algemeen langzaam variëren, maar kleine afwijkingen kunnen hebben van steekproef tot steekproef. Een goede manier om dit in blokken van 15 minuten (450 steekproeven) te coderen, is door een polynoom van de eerste, tweede of derde orde (of meer, afhankelijk van de algemene aard van uw gegevens) te passen naar het gegevensblok om de algehele vorm vast te leggen. 1

Het blok zou dan worden gecodeerd als de parameters van dat polynoom (misschien vier 16-bit getallen), plus de individuele sample-afwijkingen van dat polynoom, die vermoedelijk veel kleinere getallen kunnen zijn - misschien 450 3- of 4-bit getallen , voor een totaal van 1414 of 1864 bits in plaats van de oorspronkelijke 7200 bits - een compressieverhouding van ongeveer 4 of 5 op 1.

Als je merkt dat je geen vaste breedte kunt gebruiken voor de voorbeelddelta's, overweeg dan om Huffman-codering te gebruiken om ze weer te geven - kleine waarden krijgen korte codes, terwijl de vermoedelijk zeldzamere grote waarden langere codes krijgen . U zou nog steeds in staat moeten zijn om een ​​compressieverhouding van ongeveer 3 op 1 te krijgen, afhankelijk van uw gegevens.

1 Als blijkt dat de gegevens een cyclische component hebben, kan het handiger zijn om autoregressie of Fourier-analyse te gebruiken om de belangrijkste periodieke componenten (frequentie, fase en amplitude) te identificeren, en dan registreer de individuele voorbeelddelta's van de functie gedefinieerd door die parameters.

jpa
2020-07-29 12:56:21 UTC
view on stackexchange narkive permalink

Uw gegevens zullen waarschijnlijk twee componenten bevatten:

  • Veranderingen met lage snelheid van de werkelijke spanning
  • Willekeurige variatie vanwege ADC-ruis

Het is waarschijnlijk dat de willekeurige variatie het grootste deel van de entropie in de gegevens vertoont. Je kunt het verminderen door overbemonstering: als je bijvoorbeeld 4 samples tegelijk neemt en het resultaat deelt door 4, wordt de ruis gehalveerd.

Er is geen alom populair compressieformaat voor verliesloze compressie van ADC-samples. Gratis Lossless Audio Codec wordt soms gebruikt, maar deze is behoorlijk rekenkundig zwaar en is mogelijk niet geschikt voor uw systeem. Algemene compressie-indelingen zonder verlies, zoals DEFLATE en LZ4, nemen minder rekenkracht in beslag, maar de compressieverhouding is niet erg goed tenzij u aangepaste voorbewerkingsstappen toevoegt. Het is dus misschien het beste om een ​​aangepast compressieschema te ontwerpen.

De algemene structuur voor compressiemethoden bestaat gewoonlijk uit twee delen:

  1. Voorverwerking om de samendrukbaarheid te verbeteren: bijvoorbeeld het verschil nemen tussen twee opeenvolgende waarden of polynoomvoorspelling toepassen.
  2. Entropiecodering om elk symbool weer te geven met het minste aantal bits dat nodig is. Een veelgebruikte methode is Huffman-codes, waarbij gebruik wordt gemaakt van constante of dynamisch opgebouwde tabellen.

Een aangepast formaat dat ik met succes heb gebruikt, is om de delta tussen opeenvolgende samples te berekenen en het verschil te coderen met Elias-gammacodering. Het heeft het voordeel dat het eenvoudig te implementeren is en minder dan 1 byte per sample codering bereikt voor langzaam veranderende signalen.

Glenn Willen
2020-07-29 11:51:13 UTC
view on stackexchange narkive permalink

De beste codering die je kunt gebruiken, hangt sterk af van de distributie van je samples. U hebt ons verteld dat de delta's meestal vrij klein zijn, wat betekent dat uw eerste stap vrijwel zeker delta-codering zal zijn (elke waarde transformeren in een verschil met de vorige waarde.)

Een andere beperking is het systeem waarop je de codering uitvoert - je hebt gezegd dat het "ingebed" is, maar dat omvat een behoorlijk scala aan mogelijkheden. Je hebt ook gezegd dat SD-kaarten buiten bereik zijn, en dat je slechts 450 samples tegelijk in RAM buffert, wat inderdaad een heel klein systeem suggereert. In dat geval lijkt optimaliseren voor eenvoud en behoud van CPU / RAM in orde.

Als de meest voorkomende deltawaarde exact 0 is - dat wil zeggen, veel samples zijn hetzelfde als de vorige sample - is het waarschijnlijk een goed idee om die runs van 0 waarden eerst te "run-length coderen". (D.w.z. gewoon opslaan hoeveel er op een rij waren.)

De rest hangt verder af van hoe de verdeling van waarden eruitziet. Ik zal omwille van de oefening aannemen dat ze bijna allemaal in het bereik -64 < x < 63 liggen (d.w.z. een 7-bits geheel getal met teken). Ik neem ook aan dat het het gemakkelijkst is om met bytes te werken in plaats van met bits (wat waarschijnlijk waar is als je bijvoorbeeld C schrijft) - als dat niet waar is, kijk dan helemaal onderaan het antwoord voor een bit-wijs schema. Een heel eenvoudige byte-gewijze codering zou er ongeveer zo uit kunnen zien:

0b0xxxxxxx - een letterlijke waarde (delta) weergegeven als 7-bits geheel getal met teken in het "xxxxxxx" -gedeelte. (Waarden van -64 tot 63.)

0b10xxxxxx - een reeks nullen (delta's), waarvan de lengte wordt weergegeven door "xxxxxx" (6 bits ongetekend kunnen tot 63 uitdrukken, en als we meer nodig hebben, kunnen we gewoon nog een item toevoegen.)

0b110xxxxx 0byyyyyyyy - een letterlijke waarde (delta) weergegeven als een 13-bits geheel getal met teken in het gedeelte "xxxxxyyyyyyyyy".

0b11111111 0bxxxxxxxx 0byyyyyyyy - een letterlijke waarde (delta) weergegeven als een 16-bits geheel getal met teken. Dit is een erg inefficiënte codering (uiteraard) omdat het een 16-bits waarde omzet in een weergave van 3 bytes. Het verspilt onnodig ruimte om de output byte-uitgelijnd te houden. Deze regeling heeft alleen zin als zulke grote delta's zeer zeldzaam zijn. (Elk niet-triviaal compressieschema heeft een aantal inputs waarvan de resulterende output eigenlijk groter is; dit is een theorema van informatietheorie.)

(Het bovenstaande schema is enigszins geïnspireerd door de UTF-8-codering van Unicode.)

In tegenstelling tot Huffman-codes (vermeld in een ander antwoord), wordt de veronderstelde verdeling van waarden van tevoren vastgelegd. Dit is een deugd omdat het de zaken eenvoudig houdt, en het vermijdt dat overhead wordt toegevoegd aan het begin van elk blok samples; het is een ondeugd omdat een meer adaptief schema geen handmatige afstemming op de distributie vereist.

Als delta's veel kleiner dan -64 tot 63 vaak voorkomen, zal een betere byte-gewijs codering dan de bovenstaande meer dan één sample tegelijk moeten verwerken om beter te worden dan 2: 1 compressie (dat wil zeggen, meer dan één sample per outputbyte.)

Als bitsgewijze codering ok is, dan is een veel eenvoudiger te beschrijven schema als volgt: eerst nog delta-codering en daarna als volgt coderen. Een 0-bit wordt gevolgd door een positief geheel getal met variabele lengte dat het aantal te volgen nullen codeert; een 1 bit wordt gevolgd door een tekenbit en vervolgens een positief geheel getal met variabele lengte, die samen de volgende (delta) waarde coderen. De positieve gehele getallen met variabele lengte kunnen worden gecodeerd met een van de codes van https://en.wikipedia.org/wiki/Universal_code_(data_compression), zoals een van de Elias-codes. (Welke codering het beste is, hangt weer af van de distributie van de gegevens, maar waarschijnlijk zullen ze allemaal goed werken.)

De manier waarop u uw denkproces hier heeft afgebroken, is buitengewoon nuttig.Dank je!
@toasty Graag gedaan, ik ben blij dat dit nuttig was!
Opmerking: een paar andere mensen hebben opgemerkt dat willekeurige ADC-ruis over de monsters heen wordt gelegd, wat resulteert in willekeurige trillingen tussen elk monster.Als dit waar is (tenzij je de ruis eerst wilt filteren, voordat je comprimeert, waardoor het verlies zou lijden), heeft het geen zin om de run-length codering dingen die ik heb beschreven, omdat in de aanwezigheid van ruis die elke sample verandert,het zal nooit helpen.
Vegard
2020-07-29 11:29:47 UTC
view on stackexchange narkive permalink

Om Dave's idee uit te breiden, is een andere manier om een blok van 15 minuten op te slaan als de waarde langzaam verandert in de loop van de tijd, door alleen de wijzigingen op te slaan.

Je begint met het volledige 16-bits getal en bepaalt vervolgens hoeveel bits je nodig hebt om de grootste verandering tussen twee samples op te slaan.Als de grootste verandering bijvoorbeeld gaat van 1050 naar 1013, is het verschil -37 of 1011011 in het binaire complement van twee.Dat kost 7 bytes per sample in plaats van 16.

Dit beperkt natuurlijk uw vermogen om temperatuursprongen te registreren.Je zou een bit kunnen toevoegen die je vertelt om de volgende 16 bits te nemen en ze te interpreteren als een volledige sample (in het geval van grote veranderingen) of alleen de volgende n bits te nemen en ze als delta te interpreteren.
Michael
2020-07-29 15:46:52 UTC
view on stackexchange narkive permalink

Schrijf niet elke twee seconden gegevens.

Schrijf alleen gegevens als de wijziging een bepaalde drempel overschrijdt en neem een tijdstempel op.

Voor zowel gegevens als tijdstempel kunt u delta's (verschil met het vorige voorbeeld) loggen met minder bits en alleen de volledige breedte gebruiken als de wijziging groter is dan de breedte die u voor delta's heeft gedefinieerd.

Brian Drummond
2020-07-29 22:51:38 UTC
view on stackexchange narkive permalink

Twee manieren om het te doen:

  1. Rol je eigen compressieschema.Begin eenvoudig: als bijvoorbeeld meerdere opeenvolgende monsters dezelfde waarde hebben, gebruik dan RLL-codering.Het verfijnen van de regeling kan onderzoek en ontwikkeling vergen.De antwoorden van Dave Tweed en Glenn Willen suggereren goede benaderingen.

  2. Kies een bestaand schema.Per jpa's antwoord, FLAC komt onmiddellijk in me op (hoewel het gericht is op audiofragmentfrequenties).Als je een redelijk krachtige CPU hebt en een gemakkelijk te gebruiken softwarebibliotheek vindt, werk je met veel minder moeite.

Als je niet geïnteresseerd bent in hoogfrequente ruis, zal een laagdoorlaatfilter vóór compressie waarschijnlijk de compressieverhouding op beide manieren helpen.



Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 4.0-licentie waaronder het wordt gedistribueerd.
Loading...