daten schnell speichern
-
Bevor wir über die Software-Seite sprechen, was schafft denn dein Speichermedium für eine maximale Schreibrate? Die Webcam scheint zwar nur 480p zu unterstützen, aber selbst das sind noch über 40 MB/s. Wenn du das auf eine SD-Karte oder über USB 2.0 auf ein Medium schreiben willst, kann es schon mal eng werden.
-
Viele kleine Dateien Schreiben ist
auf jeden Fallmit an Sicherheit grenzender Wahrscheinlichkeit langsamer als einfach eine grosse Datei Schreiben.Noch schneller sollte sein wenn die grosse Datei schon gross ist, und nur mehr der Inhalt überschrieben wird (d.h. die Grösse sich nicht ändert). Dann muss das File-System nicht dauernd die File-Grösse in den Metadaten updaten.
-
Alles klar ich glaube das mit der SD Karte ist der Flaschenhals an der Geschichte.
Ich habe mal gerade nachgeschaut
http://de.wikipedia.org/wiki/SD_Memory_Card#GeschwindigkeitsklassenIch weiss zwar nich genau welche SD Karte ich habe aber es wird keine von den Uhs sein deshalb werden die Schreibzeiten bei um die 4mb/s liegen.
Ich versuche aber 752*480*2*60fps=43mb/s zu schreiben.
@ifsw da wirst du wohl recht haben.
@hustbaer Das mit der grossen Datei macht Sinn
Ich habe dieses Board als Adaptor.
https://store.gumstix.com/index.php/products/230/
Also haette ich noch Ethernet hdmi oder ggf nen USB-Stick den ich anschliessen koennte.
HDMI stream geht wohl nich(kenn ich mich zumindest nich mit aus)
also bleibt noch Ethernet oder USB Stick. Im ganzen moechte ich so 20s samplen koennen. also ca 870mB vielleicht teil ich das dann einfach so auf das ich 15mB/s auf dem USB Stick speichere 3mB/s auf der Karte und 22mB/s im Ram halte das muesste doch gehen(ich haette ca 600mB Ram die noch nich genutzt werden). Na ich werds morgen mal so probieren.
-
Vergiss die Karte, die 3mB/s sind den Aufwand nicht wert.
Öffne mit fopen die Datei auf dem USB-Stick und setze mit setvbuf einen entsprechend grossen Buffer fest. Dann einfach wie gehabt in die Datei reinspeichern, was nicht passt, wird im RAM gehalten.Grob geschätzt dürfte das ausreichen und es ist sehr wenig Aufwand, das sind etwa 3 Zeilen mehr (Buffer allokieren/freigeben und mit setvbuf).
-
dankeschoen. Ich hoffe dann nur das mein Tobi Board mit dem USB Stick klar kommt. Das ist dann ueber USB OTG aber wenn ich glueck habe klappt das ja "out of the box".
-
Lt. C++-Standard kann für einen
std::streambuf
die Methodepubsetbuf(char_type* s, streamsize n);
aufgerufen werden. Es bleibt dabei der Implementierung des konkreten Streambuf überlassen, was dann passiert!
In der Implementierung desbasic_filebuf<>
vom Microsoft Visual Studio wird hier schlicht dassetvbuf
mit 'Mode=Full-Buffering' aufgerufen - vorausgesetzt dasss
undn
!=NULL sind.Alternativ könnte man sich seinen eigenen filebuf schreiben, der mit Hilfe der OS-API und vielleicht boost.asio ein asynchrones Schreiben realisiert. Dann wäre die Geschwindigkeit nur noch durch den Zugriff auf das RAM und das Verhältnis verfügbares Memory zu physikalischer Schreibgeschwindigkeit begrenzt.
Ist natürlich aufwändig und setzt zumindest eine tiefere Kenntnis der OS-API in Sachen 'overlapping IO' voraus.
-
Werner Salomon schrieb:
Lt. C++-Standard [...] bleibt dabei der Implementierung des konkreten Streambuf überlassen, was dann passiert!
lol, you can stop reading now. Einfach genial, dieser Standard.
Microsoft Visual Studio [...] seinen eigenen filebuf schreiben [...] OS-API [...] boost.asio [...] asynchrones Schreiben realisiert [...] nur noch durch den [...] RAM [...] begrenzt [...] overlapping IO
... was insbesondere dem OP mit seinem µC mit 600mB RAM etwas nützt.
-
hey ich hab 1GB Ram ;-).
Dachte ich zumindestfree gibt mir aus
---------------total----------used--------free---------shared---buffers----cached
Mem:-------238404------146676------91728--------0--------3752-------94296
-/+ buffers/cache: 48628 189776
Swap: 0 0 0
nur 240mB laut prozessor sollte er aber 1GB haben kann man das irgendwo einstellen.
@Werner Salomon Sorry so gut kenn ich mich nich aus
p.s. USB Stick funktioiert übrigens
-
//edit hab nicht gesehen, dass du 60fps hast.
-
Wenn du die Daten auf etwa 1/2 zusammenstauchst könntest du sie lässig über USB wegschreiben.
Umrechnen in YV12?
-
naja es geht halt gerade darum die Rohdaten zu speichern. Ich hab jetzt zumindest das RAM Problem mit nem neuen OS gelöst. geht jetzt auch um einiges schneller. Immerhin 120 Bilder am Stück mit 60fps. Bin jetzt aber leider heute noch nich dazu gekommen das mit dem Buffer zu probieren. das kommt dann morgen.
lg
Felix
-
OK.
Aber ist halt so dass das Ding - wenn ich nichts übersehen habe - keinen einzigen Anschluss hat der schnell genug wäre um die ~40 MB/s aus dem Gerät rauszubringen.(OK, der HDMI Anschluss hätte theoretisch die nötige Bandbreite, aber ich kenn leider keine HDMI-Festplatten ;-))
-
flexbex schrieb:
Ich weiss zwar nich genau welche SD Karte ich habe aber es wird keine von den Uhs sein deshalb werden die Schreibzeiten bei um die 4mb/s liegen.
Ich versuche aber 752*480*2*60fps=43mb/s zu schreiben.Es gibt SD Karten die die Geschwindigkeit schaffen. Die Frage ist nur ob dein Board es schafft.
Da ich dazu keine Specs finde, kann ich das nicht sagen.
-
flexbex schrieb:
naja es geht halt gerade darum die Rohdaten zu speichern
Dennoch kann man verlustfreie Komprimierung auf die Daten anwenden. Wenn du die Rohdaten unbedingt brauchst, kannst du sie später immernoch aus den komprimierten Daten herausrechnen.
-
YV12 ist nicht verlustfrei
Und bei verlustfrei kann man auch keine Kompressionsrate garantieren. Von daher doof, wenn das zuverlässig funktionieren soll.
-
na ok welche moeglichkeit gibt es denn. die daten lien als 10bit bayer daten da. ich wuerde im naechsten schrit mit einer ((1,2,1;2,4,2;1,2,1) maske falten um so das grauwertbild zu bekommen. ich bin offen fuer komprimierungsmethoden.d
-
Wenn du 10 Bit pro Pixel reinbekommst, dann speicher auch nur 10 Bit pro Pixel. Also aus 4 solchen Werten machst du 5 Byte. Bisschen Bits Rumschieben, mehr ist das nicht. 10 statt 16 bringt dich schonmal auf 62,5% runter.
752*480*10*60/8 Byte ~~ 27,1 MB
Das könnte sich über USB 2.0 ausgehen. Je nach Hardware und Software (OS, Treiber) schafft man effektiv so 25~35 MB/Sek.
Und natürlich kannst du versuchen verlustfrei zu komprimieren. Ist aber auch nicht ganz ohne sowas zu programmieren. Wie man es angehen kann kannst du dir beim HuffYUV CODEC abgucken.
Kurzfassung: Bild in Deltawerte (Unterschied zum vorgien Pixel) umrechnen, und diese Deltawerte dann Huffman codieren. Bzw. du kannst auch nen arithmetischen Coder einsetzen, aber das ist dann nochmal komplizierter als Huffman.Bei Bayer Daten müsstest du dabei die roten, grünen und blauen Pixel getrennt codieren. (Sonst würdest du bei farbigen Stellen dauernd unnötig hohe Deltawerte rausbekommen.)
Ein paar Tips dazu, falls du es versuchen willst:
Fertige Huffman-Libs sollte es genug geben, den Teil müsstest du also nicht selbst implementieren.
Huffman ist nicht "Byte-gebunden". Die Tatsacht dass du 10 Bit Werte hast würde dabei also nicht stören. Du baust dann einfach einen Tree auf der 1024 Symbole kodieren kann.
Beim Deltawerte Erzeugen einfach unsigned rechnen und den Wert wieder auf 10 Bit "runtermaskieren". Statt -1 speicherst du also einfach 1023. 10 + 1023 = 1033, und 1033 AND 1023 = 9. Passt also.
Du kannst dabei mit fixen Symbol-Frequenzen arbeiten. D.h. du guckst dir mal die Verteilungen (Symbol-Frequenzen) der Deltawerte an die du bei ein paar unterschiedlichen Bildern (unter unterschiedlichen Lichtverhältnissen) bekommst. Die Verteilungen summierst du einfach auf und verwendest das Ergebnis als fixen Frequency-Table. Die Kompression ist dabei natürlich nicht SO gut wie wenn du für jedes Frame den Frequency-Table neu berechnest, aber dafür muss du den Frequency-Table nicht mit abspeichern, und es spart auch Rechenzeit.
-
Was mir da einfällt ist ein separater Thread, der über eine Queue mit den Daten versorgt wird und sich um die Speicherung kümmert. Dadurch wird der Haupthread nicht blockiert.
Es würde sich auch eine schnelle Komprimierung anbieten. Wie wäre es mit LZO (http://de.wikipedia.org/wiki/Lempel-Ziv-Oberhumer). Das ist sehr schnell. Durch die Komprimierung wird die Datenmenge, die auf das Speichermedium geschrieben werden muss reduziert.
Wenn mehrere Cores zur Verfügung stehen, kann man auch die Komprimierung parallelisieren. Also statt eines Speicherthreads gleich einen Threadpool.
Und wenn die CPU-Leistung im Vergleich zur I/O Leistung sehr groß ist, dann kannst Du auch höher komprimierende Algorithmen verwenden, die mehr Rechenaufwand benötigen.
-
Ich weiss nicht ob LZO (oder andere Dictionary-basierten Algorithmen) bei Bilddaten wirklich viel Sinn machen.
Delta + Entropy-Coding funktioniert dagegen bekanntermassen gut.
Und Huffman kann man über Lookup-Tables auch richtig schnell bekommen.
-
tntnet schrieb:
Was mir da einfällt ist ein separater Thread, der über eine Queue mit den Daten versorgt wird und sich um die Speicherung kümmert. Dadurch wird der Haupthread nicht blockiert.
Es würde sich auch eine schnelle Komprimierung anbieten. Wie wäre es mit LZO (http://de.wikipedia.org/wiki/Lempel-Ziv-Oberhumer). Das ist sehr schnell. Durch die Komprimierung wird die Datenmenge, die auf das Speichermedium geschrieben werden muss reduziert.
Wenn mehrere Cores zur Verfügung stehen, kann man auch die Komprimierung parallelisieren. Also statt eines Speicherthreads gleich einen Threadpool.
Und wenn die CPU-Leistung im Vergleich zur I/O Leistung sehr groß ist, dann kannst Du auch höher komprimierende Algorithmen verwenden, die mehr Rechenaufwand benötigen.
LZO ist aber keine freie Software oder? Das sieht noch GPL aus.