Jpg Bilder einlesen und skalieren
-
Wenn du mit solchen Low-Level-Algorithmen arbeitest, mache dich unbedingt mit der Funktionsweise von Zeigern, RAM und Datenstrukturen im Detail vertraut. Auch RAII musst du unbedingt anschauen. Du wirst sonst wahnsinnig viel Zeit mit Debugging verbraten, viel mehr als wenn du die Zeit in die Lektüre von C++ investiert hättest. Ich fürchte, alleine die Implementierung der Algorithmen wird schon genügend Zeit (auch für Debugging) benötigen -- wenn du dann noch Probleme mit der Programmiersprache hast, wirst du sehr schnell die Motivation verlieren
dot schrieb:
Nur um's mal erwähnt zu haben: http://libjpeg.sourceforge.net/
Es seien auch Boost.GIL und SFML erwähnt, wobei ich mit ersterem noch nie gearbeitet habe.
-
Vielen Danke für die ganzen Tipps. Bin auch schon wieder ein Stückchen voran gekommen.
Ich hab jetzt auch gleich mal ein Frage. Und zwar versuche ich grade die Zeichen in meinem Vector zu zählen. Allerdings nicht die gesamt Zahl sondern wie oft ein einzel Zeichen vorkommt. Irgendwie finde ich da nichts.
std::vector<char> veki; int Anzahl = veki.size();
Sowas hilft mir da ja leider irgendwie nicht.
Meinet wegen hab ich ein Text eingelesen der so aussieht: 11001010001 Jetzt würde ich gerne wissen wie oft die 1 und wie oft die 0 vorkommt. Habt ihr dort mal ein Tipp für mich? Problem ist auch das ich ja nicht einfach nach einem bestimmten Zeichen suche.
-
also grade für vector<char> (was im Prinzip eine Zeichenkette ist) bietet sich std::string eher an.
Zu deinem Problem:
#include <algorithm> //... std::vector<char> v; // füllen auto countZeros = std::count(std::begin(v), std::end(v), '0');
-
Ja das sieht ganz gut aus. Allerdings wären in meinem Text ja ziemlich viele verschiedene Zeichen und ich will für jedes wissen wie oft es drin ist. D.h. so müsste ich ja zig std::counts schreiben um das für jedes zu wissen. Also ich such nicht nach bestimmten Zeichen sondern will wissen wie oft welches vorkommt.
Oder kann ich da auch beliebig viel dran hängen?
auto countZeros = std::count(std::begin(v), std::end(v), '0', '1');
EDIT:
Ah ich glaube ich hab grade gefunden was ich will:Lauflängencodierung: Substitution von Folgen identischer Symbole durch Symbole eines anderen Alphabets.
-
Nein, das geht nicht.
Du solltest dir erstmal im Klaren drüber werden, wie du die Ergebnisse speichern oder nutzen willst.hast du z.B. eine überschaubare Anzahl von zu zählenden Zeichen (wie etwa '0', '1' und '2' als Beispiel), dann kannst du entweder mehrere Counts schreiben oder dir eine Liste bzw. map aufsetzen über die dann rüber iterierst.
Wenn du sämtliche Ascii-Zeichen zählen musst, dann dann setzt dir ein Zahlen Array auf und nutz die Zeichen als Index:
std::vector<std::size_t> count Chars(std::vector<char> const& s) { std::vector<std::size_t> v(std::numeric_limits<char>::max(), 0); for(std::size_t i = 0; i < v.size(); ++i) { v[i] = std::count(std::begin(s), std::end(s), static_cast<char>(i)); } return v; } // ungetestet
Wobei das nicht sonderlich gut ist und auch recht langsam sein dürfte, also es gibt da bessere Möglichkeiten
-
Enno schrieb:
Also ich such nicht nach bestimmten Zeichen sondern will wissen wie oft welches vorkommt.
Du möchtest ein Histogramm erstellen.
-
vector<size_t> countChars(vector<char> const& s) { vector<size_t> v(256); for(auto x:s) ++v[static_cast<unsigned char>(x)] return v; } // ungetestet
-
Das wäre eine schneller Lösung, z.B.
-
DirkB schrieb:
Enno schrieb:
Also ich such nicht nach bestimmten Zeichen sondern will wissen wie oft welches vorkommt.
Du möchtest ein Histogramm erstellen.
Hm ne ich glaube nicht.
Skym0sh0 schrieb:
std::vector<std::size_t> count Chars(std::vector<char> const& s) { std::vector<std::size_t> v(std::numeric_limits<char>::max(), 0); for(std::size_t i = 0; i < v.size(); ++i) { v[i] = std::count(std::begin(s), std::end(s), static_cast<char>(i)); } return v; } // ungetestet
volkard schrieb:
vector<size_t> countChars(vector<char> const& s) { vector<size_t> v(256); for(auto x:s) ++v[static_cast<unsigned char>(x)] return v; } // ungetestet
Ok das schau ich mir jetzt auch noch mal an. Was ich mich grade frage ob es schlau ist das über die Lauflänge zu machen oder so wie ihr mir das jetzt grade gezeigt habt?
Bei der Lauflänge hätte ich ja nicht alle gesamt aber könnte trotzdem ja ein Huffman Baum mit Knoten draus bauen. Weiß nicht, was haltet ihr für besser?Mit der Lauflänge hab ich mir das so gedacht:
const std::string source; std::ostringstream input("../M00001.jpg"); input << my_file.rdbuf(); source = input.str(); std::stringstream ss_dest; std::string::const_iterator it_last(source.begin()); for (std::string::const_iterator it(source.begin()); it != source.end(); ++it){ if (*it_last != *it){ ss_dest << std::distance(it_last, it) << *it_last; it_last = it; } }
-
Skym0sh0 schrieb:
also grade für vector<char> (was im Prinzip eine Zeichenkette ist) bietet sich std::string eher an.
Nein! Er hat rohe Bytes und keine Zeichen. std::string wäre nicht nur irreführend sondern auch falsch (zb der Output-Operator ist komplett sinnfrei überladen wenn es um Binärdaten geht).
-
Enno schrieb:
Hey Leute,
ich habe vor Bilder zu skalieren. Das erstmal vorweg.
Im Prinzip soll das erstmal so laufen, das ich meine .jpg datei öffne und dann nach einzelnen Hex Zeichen suchen kann. (--> http://developer.mobotix.com/docs/mxpeg_frame.html)
Problem für mich ist irgendwie finde ich sehr wenig zu dem Thema oder ich suche mit falschen Schlagwörtern.
Ich hab mir jetzt gedacht das ich die Datei in mit ifstream öffne und in einen Vektor schiebe damit ich leichter nach den Zeichen suchen kann. So in dieser art hier:
ifstream img; img.open("test.jpg" ios::binary); img.close();
Fragen:
Frag ist komm ich da dann auch an die Hex Zeichen?
Versteht ihr überhaupt was ich will? Braucht ihr mehr Infos?So geht das nicht. Das JPG-Format ist nicht so gebaut, daß Du mit unerheblichem Aufwand an die Pixels kommst. Fang mit unkomprimiertem BMP oder TGA an.
Installiere Dir http://www.imagemagick.org/script/convert.php und rufe das auf, wannimmer Du es in Deine Anwendung brauchst. Das erfüllt schon mal die meisten Wünsche direkt. Und für die anderen kannste ImageMagick benutzen, um Dir ein leicht einlesbares Format bereitzustellen.
Für JPG schau erstmal auf http://de.wikipedia.org/wiki/JPEG#Blockbildung_und_diskrete_Kosinustransformation
Lass auch unbedingt Optimierungen wie reserve zunächst weg. Insbesondere, wenn sie in die Schnittstelle der Klasse wandern. Außerdem ist reserve eh total überbewertet. Um dafür vorher einen Betriebssystemaufruf zu bezahlen, muß man schon kerngesund sein.
Optimierungen dann beim zweiten mal, wenn Du es implementierst.
Und falls es um Screenshots aus Anwendungen geht, nimm PNG statt JPG, das komprimiert in diesem Fall viel stärker und artefuckt nicht so rum.
-
Skym0sh0 schrieb:
char c; f.read(&c, sizeof(c));
wie groß ist sizeof(char) nochmal?
-
ich weiss nicht, wie groß ein char ist. aber dank c++ gibt es dafür den sizeof operator, der es mir sagt, ohne dass ich detailwissen aus dem standard oder der implementierung benötige
-
[quote="volkard"]
Enno schrieb:
So geht das nicht. Das JPG-Format ist nicht so gebaut, daß Du mit unerheblichem Aufwand an die Pixels kommst. Fang mit unkomprimiertem BMP oder TGA an.
Installiere Dir http://www.imagemagick.org/script/convert.php und rufe das auf, wannimmer Du es in Deine Anwendung brauchst. Das erfüllt schon mal die meisten Wünsche direkt. Und für die anderen kannste ImageMagick benutzen, um Dir ein leicht einlesbares Format bereitzustellen.
Für JPG schau erstmal auf http://de.wikipedia.org/wiki/JPEG#Blockbildung_und_diskrete_Kosinustransformation
Lass auch unbedingt Optimierungen wie reserve zunächst weg. Insbesondere, wenn sie in die Schnittstelle der Klasse wandern. Außerdem ist reserve eh total überbewertet. Um dafür vorher einen Betriebssystemaufruf zu bezahlen, muß man schon kerngesund sein.
Optimierungen dann beim zweiten mal, wenn Du es implementierst.
Und falls es um Screenshots aus Anwendungen geht, nimm PNG statt JPG, das komprimiert in diesem Fall viel stärker und artefuckt nicht so rum.
Hey danke erstmal für deine Antwort.
ich weiß nicht ob du alles gelesen hast aber:Enno schrieb:
Das wird wohl drauf hinaus laufen das ich das Rad neu erfinden werde. Aber danke für die Tipps. Bin auch schon auf Imagemagick und CImg gestoßen.
Trotzdem werde ich deine Tipps mir zu Herzen nehmen(reserve).
nichtkenner der chars schrieb:
ich weiss nicht, wie groß ein char ist. aber dank c++ gibt es dafür den sizeof operator, der es mir sagt, ohne dass ich detailwissen aus dem standard oder der implementierung benötige
Ein Char ist doch ein Zeichen also dem entsprechen = 1?
-
Enno schrieb:
Was ich mich grade frage ob es schlau ist das über die Lauflänge zu machen oder so wie ihr mir das jetzt grade gezeigt habt?
Bei der Lauflänge hätte ich ja nicht alle gesamt aber könnte trotzdem ja ein Huffman Baum mit Knoten draus bauen. Weiß nicht, was haltet ihr für besser?RLE bringt nur was, wenn Du lange Zeilen lang unveränderte Werte hast. Wie bei Screenshots wenn keine Farbverläufe oder Bilder beteiligt sind. Aber wenn RLE mal paßt, dann komprimiert es gewaltig stark.
Huffman bring nur was, wenn Du nicht gleichverteilte Daten hast (also fast immer). Aber Huffman komprimiert nie gewaltig stark.
Deswegen kombiniert man gerne beide. Erst RLE, dann Huffman.
-
Jain, RLE komprimiert mit zunehmender Länge besser.
Also am wenn der zu komprimierende Wert nur 1 lang ist dann erhöht sich der Speicher sogar noch. Aber je länger die sich wiederholende Buchstabenkette wird, desto effizienter ist es.
-
nichtkenner der chars schrieb:
ich weiss nicht, wie groß ein char ist. aber dank c++ gibt es dafür den sizeof operator, der es mir sagt, ohne dass ich detailwissen aus dem standard oder der implementierung benötige
Skym0sh0 sollte es aber inzwischen drin haben.
-
Skym0sh0 schrieb:
Jain, RLE komprimiert mit zunehmender Länge besser.
Also am wenn der zu komprimierende Wert nur 1 lang ist dann erhöht sich der Speicher sogar noch. Aber je länger die sich wiederholende Buchstabenkette wird, desto effizienter ist es.Na gut das mag sein aber bei mir ist nun mal klar das es nicht nur eine Länge von 1 hat.
Also denke ich das RLE schon angebracht ist.
Edit:
Oder meintest du bei sowas:
12211222211
Die erste 1 steht ja alleine udn hätte nur eine länge von 1?
-
1
5.3.3.1 schrieb:
sizeof(char), sizeof(signed char) and
sizeof(unsigned char) are 1.Wieso sollte ich mittlerweile? oO
-
Enno schrieb:
Oder meintest du bei sowas:
12211222211
Die erste 1 steht ja alleine udn hätte nur eine länge von 1?Noch ein Grund, RLE und Huffman nacheinanderzuschalten. Man hat kostenlose Escape-Zeichen.
12211222211
wäre in ASCII
49 50 50 49 49 50 50 50 50 49 49
und nach RLE vielleicht (256 als Zeichen; Jetzt kommt ein Byte=Anzahl und dann ein Byte für das sich wiederholende Zeichen)
49 50 50 49 49 256 4 50 49 49
und Huffman hat dann keinerlei Schmerzen, einen 257 großen Zeichenvorrat zu schreiben.