Πώς λειτουργεί το JPG

Πώς λειτουργεί το JPG

Η μορφή αρχείου JPG ήταν μία από τις πιο τεχνολογικά εντυπωσιακές εξελίξεις στη συμπίεση εικόνων που ήρθε στη σκηνή το 1992. Από τότε, υπήρξε κυρίαρχη δύναμη στην αναπαράσταση εικόνων ποιότητας φωτογραφιών στο Διαδίκτυο. Και για καλό λόγο. Μεγάλο μέρος της τεχνολογίας πίσω από το πώς λειτουργεί το JPG είναι εξαιρετικά περίπλοκο και απαιτεί μια σταθερή κατανόηση του τρόπου με τον οποίο το ανθρώπινο μάτι προσαρμόζεται στην αντίληψη των χρωμάτων και των άκρων.

Και επειδή είμαι σε κάτι τέτοιο (και εσείς επίσης, αν το διαβάζετε αυτό), ήθελα να αναλύσω τον τρόπο λειτουργίας της κωδικοποίησης JPG, ώστε να καταλάβουμε καλύτερα πώς να φτιάχνουμε μικρότερα αρχεία JPG.

ΤΟ ΓΙΣΤΟΣ

Το σχήμα συμπίεσης JPG κατανέμεται σε διάφορες φάσεις. Η παρακάτω εικόνα τα περιγράφει σε υψηλό επίπεδο και θα ακολουθήσουμε κάθε φάση παρακάτω.

Μετατροπή χρωμάτων

Μία από τις βασικές αρχές της συμπίεσης δεδομένων με απώλεια , είναι ότι οι ανθρώπινοι αισθητήρες δεν είναι τόσο ακριβείς όσο τα υπολογιστικά συστήματα. Επιστημονικά, το ανθρώπινο μάτι έχει μόνο τη φυσική ικανότητα να διακρίνει περίπου 10 εκατομμύρια διαφορετικά χρώματα. Ωστόσο, υπάρχουν πολλά πράγματα που μπορούν να επηρεάσουν το πώς το ανθρώπινο μάτι αντιλαμβάνεται ένα χρώμα. τέλεια επισημασμένο με ψευδαισθήσεις χρώματος ή το γεγονός ότι αυτό το φόρεμα έσπασε το Διαδίκτυο. Η ουσία είναι ότι το ανθρώπινο μάτι μπορεί να χειριστεί όμορφα σε σχέση με τα χρώματα που αντιλαμβάνεται.

Ο ποσοτικός προσδιορισμός είναι μια μορφή αυτού του αποτελέσματος στη συμπίεση της απώλειας εικόνας, ωστόσο το JPG ακολουθεί μια διαφορετική προσέγγιση σε αυτό: τα μοντέλα χρώματος . Ένας χρωματικός χώρος είναι μια συγκεκριμένη οργάνωση χρωμάτων και το χρωματικό μοντέλο αντιπροσωπεύει τον μαθηματικό τύπο για τον τρόπο αναπαραγωγής αυτών των χρωμάτων (π.χ. τριπλάσια σε RGB ή τετραπλάσια σε CMYK).

Αυτό που είναι ισχυρό για αυτήν τη διαδικασία είναι ότι μπορείτε να μετατρέψετε από ένα μοντέλο χρώματος σε άλλο , πράγμα που σημαίνει ότι μπορείτε να αλλάξετε τη μαθηματική αναπαράσταση ενός δεδομένου χρώματος, με ένα εντελώς διαφορετικό σύνολο αριθμητικών τιμών.

Για παράδειγμα, παρακάτω είναι ένα συγκεκριμένο χρώμα και είναι αναπαράσταση σε μοντέλα χρωμάτων RGB και CMYK, έχουν το ίδιο χρώμα με το ανθρώπινο μάτι, αλλά μπορούν να αναπαρασταθούν με διαφορετικό σύνολο αριθμητικών τιμών.

JPG μετατρέπει από RGB σε Y, Cb, Cr έγχρωμο μοντέλο. Που αποτελείται από Luminance (Y), Chroma Blue (Cb) και Chroma Red (Cr). Ο λόγος για αυτό, είναι ότι τα ψυχο-οπτικά πειράματα (γνωστός και ως ο τρόπος με τον οποίο λειτουργεί ο εγκέφαλος με πληροφορίες που βλέπει το μάτι) δείχνουν ότι το ανθρώπινο μάτι είναι πιο ευαίσθητο στη φωτεινότητα από ό, τι η χρωματίνη, πράγμα που σημαίνει ότι μπορεί να παραμελήσουμε μεγαλύτερες αλλαγές στην χρωματίνη χωρίς να επηρεάσουμε αντίληψη της εικόνας. Ως εκ τούτου, μπορούμε να κάνουμε επιθετικές αλλαγές στα κανάλια CbCr πριν από τις ειδοποιήσεις για τα ανθρώπινα μάτια.

Δειγματοληψία

Ένα από τα ενδιαφέροντα αποτελέσματα του χρωματικού χώρου YCbCr, είναι ότι τα προκύπτοντα κανάλια Cb / Cr έχουν λιγότερες λεπτομέρειες. Περιέχουν λιγότερες πληροφορίες από ό, τι το κανάλι Υ.

Ως αποτέλεσμα, ο αλγόριθμος JPG αλλάζει το μέγεθος των καναλιών Cb και Cr ώστε να έχουν περίπου το αρχικό τους μέγεθος (σημειώστε, υπάρχει κάποια απόχρωση στο πώς γίνεται αυτό που δεν καλύπτω εδώ…), το οποίο ονομάζεται downsampling .

Αυτό που είναι σημαντικό να σημειωθεί εδώ είναι ότι η δειγματοληψία είναι μια διαδικασία απώλειας συμπίεσης (δεν θα μπορείτε να ανακτήσετε τα ακριβή χρώματα πηγής, αλλά μόνο μια στενή προσέγγιση), αλλά ο συνολικός αντίκτυπός του στα οπτικά συστατικά του ανθρώπινου οπτικού φλοιού είναι ελάχιστος. Το Luma (Y) είναι το σημείο όπου τα ενδιαφέροντα πράγματα είναι και δεδομένου ότι έχουμε μόνο δειγματοληψία στα κανάλια CbCr, ο αντίκτυπος στο οπτικό σύστημα είναι χαμηλός.

Η εικόνα χωρίζεται σε 8x8 μπλοκ pixel

Από εδώ και πέρα, το JPG κάνει όλες τις λειτουργίες σε μπλοκ pixel 8x8. Αυτό γίνεται επειδή γενικά αναμένουμε ότι δεν υπάρχει μεγάλη διαφορά στα μπλοκ 8x8, ακόμη και σε πολύ περίπλοκες φωτογραφίες, τείνει να υπάρχει κάποια ομοιότητα στις τοπικές περιοχές. αυτή η ομοιότητα θα εκμεταλλευτούμε αργότερα κατά τη συμπίεση μας.

Αξίζει να σημειωθεί ότι σε αυτό το σημείο, παρουσιάζουμε ένα από τα πρώτα κοινά «αντικείμενα» κωδικοποίησης JPG. Η «αιμορραγία χρώματος» είναι όπου τα χρώματα κατά μήκος των αιχμηρών άκρων μπορούν να «αιμορραγούν» στην άλλη πλευρά. Αυτό οφείλεται στο γεγονός ότι τα κανάλια χρωματικότητας, τα οποία εκφράζουν το χρώμα των εικονοστοιχείων, είχαν κατά μέσο όρο κάθε μπλοκ 4 εικονοστοιχείων σε ένα μόνο χρώμα, και μερικά από αυτά τα μπλοκ διασχίζουν την αιχμηρή άκρη.

Διακριτός μετασχηματισμός συνημίτονου

Μέχρι αυτό το σημείο, τα πράγματα ήταν αρκετά ήρεμα. Χρώματα, χαμηλή δειγματοληψία και αποκλεισμός είναι απλά πράγματα στον κόσμο της συμπίεσης εικόνας. Αλλά τώρα ... τώρα εμφανίζονται τα πραγματικά μαθηματικά.

Το βασικό στοιχείο του μετασχηματισμού DCT, είναι ότι υποθέτει ότι οποιοδήποτε αριθμητικό σήμα μπορεί να αναδημιουργηθεί χρησιμοποιώντας ένα συνδυασμό λειτουργιών συνημίτονο.

Για παράδειγμα, εάν έχουμε αυτό το γράφημα παρακάτω:

Μπορείτε να δείτε ότι είναι στην πραγματικότητα ένα άθροισμα cos (x) + cos (2x) + cos (4x)

Ίσως μια καλύτερη εμφάνιση αυτού, είναι η πραγματική αποκωδικοποίηση μιας εικόνας, δεδομένης μιας σειράς λειτουργιών συνημίτονο σε έναν 2D χώρο. Για να το δείξω αυτό, παρουσιάζω ένα από τα πιο εκπληκτικά GIF στο Διαδίκτυο: κωδικοποίηση ενός μπλοκ pixel 8x8 με χρήση συνημίτων σε έναν 2D χώρο:

Αυτό που παρακολουθείτε εδώ είναι η ανακατασκευή μιας εικόνας (αριστερό πλαίσιο). Κάθε πλαίσιο, παίρνουμε μια νέα τιμή βάσης (δεξί πλαίσιο) και πολλαπλασιάζουμε με μια τιμή βάρους (κείμενο δεξιού πίνακα) για να παράγουμε τη συμβολή στην εικόνα (κεντρικό πλαίσιο)

Όπως μπορείτε να δείτε, αθροίζοντας διάφορες τιμές συνημίτονο σε βάρος, μπορούμε να ανακατασκευάσουμε την αρχική μας εικόνα (αρκετά καλά ...)

Αυτό είναι το θεμελιώδες υπόβαθρο για το πώς λειτουργεί το Discrete Cosine Transform. Η ιδέα είναι ότι οποιοδήποτε μπλοκ 8x8 μπορεί να αναπαρασταθεί ως άθροισμα σταθμισμένων μετασχηματισμένων συνημίτων, σε διάφορες συχνότητες. Το τέχνασμα με όλο αυτό το πράγμα, είναι να καταλάβουμε ποιες συνημίτονες εισροές θα χρησιμοποιηθούν και πώς θα πρέπει να σταθμίζονται μαζί.

Αποδεικνύεται ότι το πρόβλημα « τι συνημίτονα να χρησιμοποιήσετε» είναι αρκετά εύκολο. Μετά από πολλές δοκιμές, επιλέχθηκε ένα σύνολο τιμών συνημίτονο για να παράγει τα καλύτερα αποτελέσματα, είναι οι βασικές μας λειτουργίες και απεικονίζονται στην παρακάτω εικόνα.

Όσον αφορά το πρόβλημα «πώς πρέπει να σταθμίζονται μαζί», απλώς (HA!) Εφαρμόστε αυτόν τον τύπο.

Θα σας ελευθερώσω τι σημαίνουν όλες αυτές οι τιμές, μπορείτε να τις δείτε στη σελίδα της wikipedia.

Το βασικό αποτέλεσμα είναι ότι για ένα μπλοκ pixel 8x8 σε κάθε κανάλι χρώματος, η εφαρμογή των παραπάνω λειτουργιών τύπου και βάσης θα δημιουργήσει μια νέα μήτρα 8x8, η οποία αντιπροσωπεύει τα βάρη που θα χρησιμοποιηθούν κατά την ανοικοδόμηση. Ακολουθεί ένα γραφικό της διαδικασίας:

Αυτός ο πίνακας, G, αντιπροσωπεύει τα βάρη βάσης που πρέπει να χρησιμοποιηθούν για την ανασυγκρότηση της εικόνας (η μικρή δεκαδική τιμή στην κάτω δεξιά πλευρά της κινούμενης εικόνας παραπάνω). Βασικά, για κάθε βάση, το πολλαπλασιάζουμε με το βάρος σε αυτό το πλέγμα, αθροίζουμε το όλο πράγμα και παίρνουμε την εικόνα που προκύπτει.

Σε αυτό το σημείο, δεν εργαζόμαστε πλέον σε χρωματικούς χώρους, αλλά μάλλον απευθείας με το G Matrix (βάρη βάσης), όλη η περαιτέρω συμπίεση γίνεται απευθείας σε αυτήν τη μήτρα.

Το πρόβλημα εδώ όμως είναι ότι τώρα μετατρέψαμε ακέραιους αριθμούς byte-aligned σε πραγματικούς αριθμούς. Που φουσκώνει αποτελεσματικά τις πληροφορίες μας (μετακίνηση από 1 byte σε 1 float (4 bytes)). Για να το λύσουμε και να αρχίσουμε να παράγουμε πιο σημαντική συμπίεση, προχωράμε στη φάση κβαντοποίησης.

Κβαντισμός

Επομένως, δεν θέλουμε να συμπιέσουμε τα δεδομένα κινητής υποδιαστολής. Αυτό θα φουσκώσει τη ροή μας και δεν θα είναι αποτελεσματικό. Για το σκοπό αυτό, θα θέλαμε να βρούμε έναν τρόπο να μετατρέψουμε τον πίνακα βάρη σε τιμές στο διάστημα [0,255]. Άμεσα, θα μπορούσαμε να το κάνουμε αυτό βρίσκοντας την τιμή min / max για τον πίνακα (-415.38 και 77.13, αντίστοιχα) και διαιρώντας κάθε αριθμό σε αυτό το εύρος για να μας δώσει μια τιμή μεταξύ [0,1] στην οποία πολλαπλασιάζουμε επί 255 για να πάρουμε την τελική μας αξία.

Για παράδειγμα: [34.12- -415.38] / [77.13 - -415.38] * 255 = 232

Αυτό λειτουργεί, αλλά η αντιστάθμιση είναι μια σημαντική μείωση ακριβείας. Αυτή η κλιμάκωση θα παράγει μια άνιση κατανομή τιμών, το αποτέλεσμα της οποίας είναι σημαντική απώλεια οπτικής εικόνας.

Αντ 'αυτού, το JPG ακολουθεί διαφορετική διαδρομή. Αντί να χρησιμοποιεί το εύρος τιμών στη μήτρα καθώς είναι η τιμή κλιμάκωσης, αντί να χρησιμοποιεί έναν προκαθορισμένο πίνακα παραγόντων ποσοτικοποίησης. Αυτά τα QF δεν χρειάζεται να είναι μέρος της ροής, αλλά μπορούν να είναι μέρος του ίδιου του κωδικοποιητή.

Αυτό το παράδειγμα δείχνει μια κοινά χρησιμοποιούμενη μήτρα παραγόντων ποσοτικοποίησης, ένας για κάθε εικόνα βάσης,

Τώρα χρησιμοποιούμε τους πίνακες Q και G, για να υπολογίσουμε τον κβαντικό πίνακα συντελεστών DCT:

Για παράδειγμα, χρησιμοποιώντας τις τιμές G [0,0] = - 415,37 και Q [0,0] = 16:

Αποτέλεσμα σε τελικό πίνακα:

Παρατηρήστε πόσο απλούστερη γίνεται η μήτρα - περιέχει τώρα μεγάλο αριθμό καταχωρήσεων που είναι μικρές ή μηδενικές, καθιστώντας πολύ πιο εύκολο να συμπιέσετε.

Ως γρήγορη άκρη, εφαρμόζουμε αυτήν τη διαδικασία στα κανάλια Y, CbCr ανεξάρτητα και ως εκ τούτου χρειαζόμαστε δύο διαφορετικούς πίνακες: ένα για το Y και το άλλο για τα κανάλια C:

Ο ποσοτικός προσδιορισμός συμπιέζει την εικόνα με δύο σημαντικούς τρόπους: ένας, περιορίζει το πραγματικό εύρος των βαρών, μειώνοντας τον αριθμό των bit που απαιτούνται για την αναπαραγωγή τους. Δύο, πολλά από τα βάρη γίνονται ίδια ή μηδενικά, βελτιώνοντας τη συμπίεση στο τρίτο βήμα, κωδικοποίηση εντροπίας.

Ως τέτοια η κβαντοποίηση είναι η κύρια πηγή τεχνουργημάτων JPEG. Επειδή οι εικόνες στην κάτω δεξιά τείνουν να έχουν τους μεγαλύτερους διαχωριστές κβαντοποίησης, τα ευρήματα JPEG τείνουν να μοιάζουν με συνδυασμούς αυτών των εικόνων. Ο πίνακας των παραγόντων ποσοτικοποίησης μπορεί να ελεγχθεί άμεσα αλλάζοντας το «επίπεδο ποιότητας» του JPEG, το οποίο κλιμακώνει τις τιμές του πάνω ή κάτω (θα το καλύψουμε σε ένα λεπτό)

Συμπίεση

Μέχρι τώρα, επιστρέφουμε στον κόσμο των ακέραιων τιμών και μπορούμε να προχωρήσουμε με την εφαρμογή ενός σταδίου συμπίεσης χωρίς απώλειες. Ωστόσο, όταν κοιτάζετε τα μετασχηματισμένα δεδομένα μας, θα πρέπει να παρατηρήσετε κάτι ενδιαφέρον:

Καθώς μετακινείτε από πάνω αριστερά προς τα κάτω δεξιά, η συχνότητα των μηδενικών αυξάνεται. Αυτό μοιάζει με πρωταρχικό ύποπτο για κωδικοποίηση μήκους εκτέλεσης. Όμως, οι παραγγελίες σειράς-μεγάλων και μεγάλων στηλών δεν είναι ιδανικές εδώ, καθώς αυτό θα παρεμποδίσει αυτές τις διαδρομές μηδενικών, αντί να τα συσκευάζει όλα μαζί.

Αντ 'αυτού, ξεκινάμε με την επάνω αριστερή γωνία και το ζιγκ-ζαγκ σε ένα διαγώνιο μοτίβο κατά μήκος της μήτρας, πηγαίνοντας πίσω και πίσω μέχρι να φτάσουμε στην κάτω δεξιά γωνία.

Το αποτέλεσμα του luma πίνακα μας, με αυτήν τη σειρά, γίνεται:

−26, −3,0, −3, −2, −6,2, −4,1, −3,1,1,5,1,2, −1,1, −1,2,0,0 , 0,0,0, -1, -1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

Μόλις τα δεδομένα είναι σε αυτήν τη μορφή, τα επόμενα βήματα είναι απλά: εκτελέστε το RLE στην ακολουθία και, στη συνέχεια, εφαρμόστε κάποιο στατιστικό κωδικοποιητή (Huffman / Arithmetic / ANS) στα αποτελέσματα.

Και Μπομ. Το μπλοκ σας είναι πλέον κωδικοποιημένο JPG.

Κατανόηση της παραμέτρου ποιότητας

Τώρα που καταλαβαίνετε πώς δημιουργούνται πραγματικά αρχεία JPG, αξίζει να επανεξετάσετε την έννοια της παραμέτρου ποιότητας που συνήθως βλέπετε κατά την εξαγωγή εικόνων JPG από το Photoshop (ή τι άλλο).

Αυτή η παράμετρος, την οποία θα ονομάσουμε q, είναι ακέραιος αριθμός από 1 έως 100. Θα πρέπει να θεωρήσετε το q ως μέτρο της ποιότητας της εικόνας: οι υψηλότερες τιμές του q αντιστοιχούν σε εικόνες υψηλότερης ποιότητας και μεγαλύτερα μεγέθη αρχείων.

Αυτή η ποιοτική τιμή χρησιμοποιείται κατά τη φάση κβαντοποίησης, για την κατάλληλη κλιμάκωση των παραγόντων ποσοτικοποίησης. Έτσι, ανάλογα με το βάρος βάσης, το βήμα κβαντοποίησης μοιάζει τώρα με στρογγυλό (Gi, k / alpha * Qi, k)

Όπου το σύμβολο άλφα δημιουργείται ως αποτέλεσμα της παραμέτρου ποιότητας.

Όταν αυξάνεται είτε το alpha είτε το Q [x, y] (θυμηθείτε ότι οι μεγάλες τιμές του alpha αντιστοιχούν σε μικρότερες τιμές της παραμέτρου ποιότητας q), χάνονται περισσότερες πληροφορίες και το μέγεθος του αρχείου μειώνεται .

Ως εκ τούτου, εάν θέλετε ένα μικρότερο αρχείο, με κόστος περισσότερων οπτικών αντικειμένων, μπορείτε να ορίσετε χαμηλότερη ποιότητα ποιότητας κατά τη φάση εξαγωγής.

Παρατηρήστε παραπάνω, στην εικόνα χαμηλότερης ποιότητας, πώς βλέπουμε σαφή σημάδια του σταδίου αποκλεισμού, καθώς και το στάδιο κβαντοποίησης.

Πιθανώς το πιο σημαντικό, είναι ότι η παράμετρος ποιότητας ποικίλλει ανάλογα με την εικόνα . Δεδομένου ότι κάθε εικόνα είναι μοναδική και παρουσιάζει διαφορετικούς τύπους οπτικών αντικειμένων, η τιμή Q θα είναι και μοναδική.

συμπέρασμα

Μόλις καταλάβετε πώς λειτουργεί ο αλγόριθμος JPG, μερικά πράγματα γίνονται εμφανή:

  1. Η σωστή τιμή ποιότητας, ανά εικόνα, είναι σημαντικό να βρεθεί η αντιστάθμιση μεταξύ οπτικής ποιότητας και μεγέθους αρχείου.
  2. Δεδομένου ότι αυτή η διαδικασία βασίζεται σε μπλοκ, τα αντικείμενα τείνουν να εμφανίζονται σε μπλοκαρίσματα ή «κουδούνισμα»
  3. Δεδομένου ότι τα επεξεργασμένα μπλοκ δεν αναμιγνύονται μεταξύ τους, το JPG γενικά αγνοεί την ευκαιρία να συμπιέσει μεγάλα τμήματα παρόμοιων μπλοκ μαζί. Η αντιμετώπιση αυτής της ανησυχίας είναι κάτι που μπορεί να κάνει η μορφή WebP

Και αν θέλετε να παίξετε με όλα αυτά μόνοι σας, όλη αυτή η τρέλα μπορεί να ενσωματωθεί σε ένα αρχείο γραμμής ~ 1000.

Γεια σου

Θέλετε να μάθετε πώς να κάνετε τα αρχεία JPG σας μικρότερα;

Θέλετε να μάθετε πώς λειτουργούν τα αρχεία PNG ή πώς να τα κάνετε μικρότερα;

Θέλετε περισσότερη καλοσύνη συμπίεσης δεδομένων; Αγοράστε το βιβλίο μου!