La position actuelle:Accueil du site>Expérience II Yuv
Expérience II Yuv
2022-07-23 07:57:57【Myster Kid】
TGA to YUV Conversion de fichiers et instances
Catalogue des articles
Un.、TGAStructure du fichier
| Nom | Offset(Byte) | Longueur(Byte) | Description |
|---|---|---|---|
| ID Length | 0 | 1 | Longueur du champ d'information de l'image:Pour0Quand indique qu'il n'y a pas de champ d'information d'image |
| Colour Map Type | 1 | 1 | Type de palette: 0:Pas de palette 1:Il y a une palette de couleurs |
| Image Type Code | 2 | 1 | |
| Colour Map Offset | 3 | 2 | Index d'entrée de la table des couleurs |
| Colour Map Length | 5 | 2 | Tableau des couleurs totalentryNombre |
| Colour Map Depth | 7 | 1 | Chaque tableau de couleursentryNombre de chiffres: 16:Targa 16 24:Targa 24 32:Targa 32 |
| X Origin | 8 | 2 | En bas à gauche de l'imagexCoordonnées |
| Y Origin | 10 | 2 | En bas à gauche de l'imageyCoordonnées |
| Width | 12 | 2 | Largeur de l'image |
| Height | 14 | 2 | Image haute |
| Bits Per Pixel | 16 | 1 | Nombre de bits occupés par pixel de l'image |
| Image Descriptor | 17 | 1 | 0:Pas de données d'image 1:Pas de compression、 Image avec Palette 2:Pas de compression、 Sans Palette RGBImages 3: Image en noir et blanc non compressée 9: Image codée en cours de route avec Palette 10: Code de course RGBImages 11: Image compressée en noir et blanc 32:UtiliserHuffman、Delta、 Compression d'images codées avec Palette 33:UtiliserHuffman、Delta、 Compression d'images codées avec Palette ,4 Traitement de type Quadtree |
| Image Identification Field | 18 | Variable | La longueur du champ est déterminée par ID LengthDésignation des champs. Généralement ignoré . Stocker plus d'informations si nécessaire , Peut être placé après les données d'image |
| Colour Map Data | Variable | Variable | SiColour Map TypePour 0, Le champ n'existe pas . Chaque Palette entry La longueur peut être 4(RGBA)、3(RGB)Ou2Octets(No1OctetsGGBBBBB,No2OctetsARRRRRGG) |
| Image Data Field | Variable | Variable | Attention!,TGA Les fichiers sont stockés à petite échelle ,RGB Composant à B、G、RStockage séquentiel, Les données d'image sont stockées à partir du coin inférieur gauche |
2.、Idées expérimentales
- PourTGA Le fichier crée la structure de l'en - tête du fichier , Lire le contenu de l'en - tête de fichier dans ;
- Selon les informations de l'en - tête du fichier ,Calculer le décalage, Localiser le point de départ des données d'image ;
- Lire les données d'image,C'est exact.RLE L'image compressée est décodée ,Et selonBits Per PixelLa différence entre,SéparationR、G、BComposante;
- Inverser l'image vers le haut et vers le bas ,Lire comme suit:RGBComment les fichiers sont stockés
- Utiliserrgb2yuvFonctions, C'est terminé. YUVConversion de fichiers
Trois、Code
declarations.h
#pragma once
#include <iostream>
typedef struct
{
char idLength = 0; // Length of identification field (length = 1B, offset = 0B)
char colourMapType = 0; // Colour map type (length = 1B, offset = 1B): 0 for no colour map included, 1 for colour map included
char imageTypeCode = 0; // Image type code (length = 1B, offset = 2B): 2 for uncompressed & unmapped RGB image, 10 for run length encoded & unmapped RGB image
/* Colour map specification (all set to 0 if colour map type is 0) */
short colourMapOffset = 0; // Colour map origin (length = 2B, offset = 3B): index of first colour map entry
short colourMapLength = 0; // Colour map length (length = 2B, offset = 5B): number of colour map entries
char colourMapDepth = 0; // Colour map depth (length = 1B, offfset = 7B): number of bits in each entry. 16 for the Targa 16, 24 for the Targa 24, 32 for the Targa 32
/* Image specification */
short x_origin = 0; // X coordinate of the lower left corner (length = 2B, offset = 8B)
short y_origin = 0; // Y coordinate of the lower left corner (length = 2B, offset = 10B)
short width = 0; // Width of image (length = 2B, offset = 12B)
short height = 0; // Height of image (length = 2B, offset = 14B)
char bitsPerPixel = 0; // Number of bits in each pixel (length = 1B, offset = 16B)
char imageDescriptor = 0; // Image descripter byte (length = 1B, offset = 17B)
} HEADER;
typedef struct
{
unsigned char r, g, b, a;
} PIXEL;
void ReadTgaHeader(HEADER* tgaHdPtr, FILE* tgaPtr);
void ReadColourData(HEADER* tgaHdPtr, PIXEL* colourData, FILE* tgaPtr);
void Trans2RgbFormat(PIXEL* colourData, unsigned char* rgbBuff, HEADER* tgaHdPtr);
void rgb2yuv(FILE* yuvPtr, int width, int height, unsigned char* rgbBuff);
ReadTgaHeader.cpp
#include <iostream>
#include "declarations.h"
using namespace std;
void ReadTgaHeader(HEADER* tgaHdPtr, FILE* tgaPtr)
{
/* Read data in TGA file header fields */
tgaHdPtr->idLength = fgetc(tgaPtr);
tgaHdPtr->colourMapType = fgetc(tgaPtr);
tgaHdPtr->imageTypeCode = fgetc(tgaPtr);
fread(&tgaHdPtr->colourMapOffset, 2, 1, tgaPtr);
fread(&tgaHdPtr->colourMapLength, 2, 1, tgaPtr);
tgaHdPtr->colourMapDepth = fgetc(tgaPtr);
fread(&tgaHdPtr->x_origin, 2, 1, tgaPtr);
fread(&tgaHdPtr->y_origin, 2, 1, tgaPtr);
fread(&tgaHdPtr->width, 2, 1, tgaPtr);
fread(&tgaHdPtr->height, 2, 1, tgaPtr);
tgaHdPtr->bitsPerPixel = fgetc(tgaPtr);
tgaHdPtr->imageDescriptor = fgetc(tgaPtr);
/* Display header info on screen */
cout << "\nTGA file header information:\n";
printf("ID length: %d\n", tgaHdPtr->idLength);
printf("Colour Map type: %d\n", tgaHdPtr->colourMapType);
printf("Image type code: %d\n", tgaHdPtr->imageTypeCode);
printf("Colour map offset: %d\n", tgaHdPtr->colourMapOffset);
printf("Colour map length: %d\n", tgaHdPtr->colourMapLength);
printf("Colour map depth: %d\n", tgaHdPtr->colourMapDepth);
printf("X origin: %d\n", tgaHdPtr->x_origin);
printf("Y origin: %d\n", tgaHdPtr->y_origin);
printf("Width: %d\n", tgaHdPtr->width);
printf("Height: %d\n", tgaHdPtr->height);
printf("Image pixel size: %d\n", tgaHdPtr->bitsPerPixel);
printf("Descriptor: %d\n\n", tgaHdPtr->imageDescriptor);
}
ReadColourData.cpp
#include "declarations.h"
void SeparateRGBA(PIXEL* pixel, unsigned char* rgba, int bytesPerPixel)
{
switch (bytesPerPixel)
{
case 4:
pixel->r = rgba[2];
pixel->g = rgba[1];
pixel->b = rgba[0];
pixel->a = rgba[3];
break;
case 3:
pixel->r = rgba[2];
pixel->g = rgba[1];
pixel->b = rgba[0];
pixel->a = 255;
break;
case 2:
pixel->r = (rgba[1] & 0b01111100) << 1;
pixel->g = ((rgba[1] & 0b00000011) << 6) | ((rgba[0] & 0b11100000) >> 2);
pixel->b = (rgba[0] & 0b00011111) << 3;
pixel->a = (rgba[1] & 0b10000000);
break;
default:
break;
}
}
void ReadColourData(HEADER* tgaHdPtr, PIXEL* colourData, FILE* tgaPtr)
{
int bytesPerPx = tgaHdPtr->bitsPerPixel / 8; // Bytes per pixel
unsigned char tempRGBA[4]; // Temporary buffer for the RGBA data of 1 pixel
int n = 0; // nth pixel
while (n < tgaHdPtr->width * tgaHdPtr->height)
{
switch (tgaHdPtr->imageTypeCode)
{
/* Uncompressed, unmapped RGB image */
case 2:
{
/* Read the colour data of 1 pixel */
if (fread(tempRGBA, 1, bytesPerPx, tgaPtr) != bytesPerPx)
{
printf("ERROR!!! Unexpected end of file at pixel %d.\n", n);
exit(-1);
}
SeparateRGBA(&(colourData[n]), tempRGBA, bytesPerPx);
//printf("%-4x%-4x%-4x\n", colourData[n].b, colourData[n].g, colourData[n].r); // Check
n++;
break;
}
/* Run length encoded, unmapped RGB image */
case 10:
{
unsigned char tempPktHeader; // Temporary buffer for the packet header
int pktHdID = 0; // Determines if it's an RL packet or a raw packet
int pktRunSize = 0; // Run size (the number of pixels in this packet)
/* Read the packet header */
if (fread(&tempPktHeader, 1, 1, tgaPtr) != 1)
{
printf("ERROR!!! Unexpected end of file at pixel %d.\n", n);
exit(-1);
}
pktHdID = (tempPktHeader & 0x80) >> 7;
pktRunSize = (tempPktHeader & 0x7F) + 1;
/* Raw packet */
if (pktHdID == 0)
{
for (int i = 0; i < pktRunSize; i++)
{
if (fread(tempRGBA, 1, bytesPerPx, tgaPtr) != bytesPerPx)
{
printf("ERROR!!! Unexpected end of file at pixel %d.\n", n);
exit(-1);
}
SeparateRGBA(&(colourData[n]), tempRGBA, bytesPerPx);
n++;
}
}
/* RL packet */
else if (pktHdID == 1)
{
if (fread(tempRGBA, 1, bytesPerPx, tgaPtr) != bytesPerPx)
{
printf("ERROR!!! Unexpected end of file at pixel %d.\n", n);
exit(-1);
}
for (int i = 0; i < pktRunSize; i++)
{
SeparateRGBA(&(colourData[n]), tempRGBA, bytesPerPx);
n++;
}
}
else
{
printf("ERROR!!! Unexpected invalid value of packet header ID.\n");
exit(-1);
}
break;
}
default:
break;
}
}
}
Trans2RgbFormat.cpp
#include "declarations.h"
void Trans2RgbFormat(PIXEL* colourData, unsigned char* rgbBuff, HEADER* tgaHdPtr)
{
/* Write RGB data in .rgb format into rgbBuff */
int w = tgaHdPtr->width;
int h = tgaHdPtr->height;
for (int i = 0; i < h; i++) // i for row of image
{
for (int j = 0; j < w; j++) // j for column of image
{
int rgbPxNum = (h - 1 - i) * w + j; // Pixel number in RGB file
int tgaPxNum = i * w + j; // Pixel number in TGA file
rgbBuff[3 * rgbPxNum + 2] = colourData[tgaPxNum].r;
rgbBuff[3 * rgbPxNum + 1] = colourData[tgaPxNum].g;
rgbBuff[3 * rgbPxNum] = colourData[tgaPxNum].b;
}
}
}
rgb2yuv.cpp
#include <iostream>
#include "declarations.h"
int rgb66[256], rgb129[256], rgb25[256];
int rgb38[256], rgb74[256], rgb112[256];
int rgb94[256], rgb18[256];
void rgbLookupTable()
{
for (int i = 0; i < 256; i++)
{
rgb66[i] = 66 * i;
rgb129[i] = 129 * i;
rgb25[i] = 25 * i;
rgb38[i] = 38 * i;
rgb74[i] = 74 * i;
rgb112[i] = 112 * i;
rgb94[i] = 94 * i;
rgb18[i] = 18 * i;
}
}
void rgb2yuv(FILE* yuvPtr, int width, int height, unsigned char* rgbBuff)
{
int pxCount = width * height;
unsigned char* yBuff = new unsigned char[pxCount]; // Buffer for Y component
unsigned char* uBuff = new unsigned char[pxCount / 4]; // Buffer for U component
unsigned char* vBuff = new unsigned char[pxCount / 4]; // Buffer for V component
unsigned char* uBuff444 = new unsigned char[pxCount]; // Buffer for U component in 4:4:4 format
unsigned char* vBuff444 = new unsigned char[pxCount]; // Buffer for V component in 4:4:4 format
// RGB to YUV (4:4:4)
for (int i = 0; i < pxCount; i++) // i for pixel number
{
unsigned char r = rgbBuff[3 * i + 2]; // R component of the ith pixel
unsigned char g = rgbBuff[3 * i + 1]; // G component of the ith pixel
unsigned char b = rgbBuff[3 * i]; // B component of the ith pixel
rgbLookupTable();
yBuff[i] = ((rgb66[r] + rgb129[g] + rgb25[b]) >> 8) + 16;
uBuff444[i] = ((-rgb38[r] - rgb74[g] + rgb112[b]) >> 8) + 128;
vBuff444[i] = ((rgb112[r] - rgb94[g] - rgb18[b]) >> 8) + 128;
}
// 4:4:4 to 4:2:0
for (int i = 0; i < height; i += 2)
{
for (int j = 0; j < width; j += 2)
{
uBuff[i / 2 * width / 2 + j / 2] = uBuff444[i * width + j];
vBuff[i / 2 * width / 2 + j / 2] = vBuff444[i * width + j];
}
}
delete[]uBuff444;
delete[]vBuff444;
fwrite(yBuff, sizeof(unsigned char), pxCount, yuvPtr);
fwrite(uBuff, sizeof(unsigned char), pxCount / 4, yuvPtr);
fwrite(vBuff, sizeof(unsigned char), pxCount / 4, yuvPtr);
}
main.cpp
#include <iostream>
#include "declarations.h"
using namespace std;
int main(int argc, char* argv[])
{
/* Declarations */
FILE* tgaFilePtr, * yuvFilePtr;
//FILE* rgbFilePtr;
HEADER hd; // Structure variable for TGA file header
int w, h, pxCount;
const char* tgaFileName = "snow32RLE.tga";
const char* yuvFileName = "snow32RLE.yuv";
//const char* rgbFileName = "snow32RLE.rgb";
PIXEL* rgbaData = NULL; // Entire RGBA data of TGA file; used for future funtions
unsigned char* rgbBuffer = NULL; // RGB data of TGA file (in .rgb format); extracted from rgbaData; used for tga2yuv
int offset = 0;
/* Open the files */
if (fopen_s(&tgaFilePtr, tgaFileName, "rb") == 0)
{
cout << "Successfully opened \"" << tgaFileName << "\".\n";
}
else
{
cout << "Failed to open \"" << tgaFileName << "\".\n";
exit(-1);
}
if (fopen_s(&yuvFilePtr, yuvFileName, "wb") == 0)
{
cout << "Successfully opened \"" << yuvFileName << "\".\n";
}
else
{
cout << "Failed to open \"" << yuvFileName << "\".\n";
exit(-1);
}
//if (fopen_s(&rgbFilePtr, rgbFileName, "wb") == 0)
//{
// cout << "Successfully opened \"" << rgbFileName << "\".\n";
//}
//else
//{
// cout << "Failed to open \"" << rgbFileName << "\".\n";
// exit(-1);
//}
/* Read and display the header fields */
ReadTgaHeader(&hd, tgaFilePtr);
w = hd.height;
h = hd.width;
pxCount = w * h;
/* Space allocation */
rgbaData = new PIXEL[hd.width * hd.height];
memset(rgbaData, 0, hd.height * hd.width); // Initialisation
rgbBuffer = new unsigned char[hd.width * hd.height * 3];
memset(rgbBuffer, 0, hd.height * hd.width * 3); // Initialisation
/* Developed function check & invalidation check */
if (hd.imageTypeCode != 2 && hd.imageTypeCode != 10)
{
cout << "Can only handle image type 2 (uncompressed, unmapped RGB) & image type 10 (run length encoded, unmapped RGB).\nOther options being developed.\n";
exit(-1);
}
if (hd.bitsPerPixel != 16 && hd.bitsPerPixel != 24 && hd.bitsPerPixel != 32)
{
cout << "Invalid value of image pixel size!\nCan only handle pixel depths of 16, 24, and 32.\n";
exit(-1);
}
if (hd.colourMapType != 0 && hd.colourMapType != 1)
{
cout << "Invalid value of colour map type!\nCan only handle colour map types of 0 and 1.\n";
exit(-1);
}
/* Skip over unnecessary chunks */
offset += hd.idLength;
offset += hd.colourMapType * hd.colourMapLength * hd.colourMapDepth;
cout << offset << " byte(s) skipped over.\n\n";
fseek(tgaFilePtr, offset, SEEK_CUR); // Skip 'offset' bytes from the end of header
/* Read the image RGB (A, if exists) data */
ReadColourData(&hd, rgbaData, tgaFilePtr);
/* Transform .tga formatted RGB data into .rgb format */
Trans2RgbFormat(rgbaData, rgbBuffer, &hd);
//fwrite(rgbBuffer, 3, pxCount, rgbFilePtr);
/* Transform RGB into YUV */
rgb2yuv(yuvFilePtr, w, h, rgbBuffer);
delete[]rgbaData;
delete[]rgbBuffer;
//fclose(rgbFilePtr);
fclose(tgaFilePtr);
fclose(yuvFilePtr);
}
Quatre、Résultats des opérations
Les images d'essai utilisées dans l'expérience sont les suivantes: “snow.jpeg”AdoptionAdobe PhotoshopDe la transformation“snow16.tga”“snow24.tga”Et“snow32.tga”.
L'image originale est la suivante: :
ParRLECompriméTarga 32Exemple d'image,Le résultat est:
Targa 32 (Image Type Code = 10) Résultats de sortie de la console de débogage
Utiliser l'image convertie avec YUV Viewer PlusOuvre.,Les résultats sont les suivants::
Après conversionYUVImages(Image Type Code = 2)
Après conversionYUVImages(Image Type Code = 10)
Mentions de copyright
Auteur de cet article [Myster Kid],Réimpression s’il vous plaît apporter le lien vers l’original, merci
https://fra.chowdera.com/2022/204/202207222136291414.html
Recommandé par sidebar
- Comment le détournement de DNS peut - il être parfaitement réparé? Comment résoudre le problème du détournement de DNS
- Flask Cross - Domain
- Mise en œuvre de la pile de chaînes (langage c)
- Lire attentivement le document DETR et analyser la structure du modèle
- [FPGA]: IP Core - - DDR3
- L'applet Wechat ne peut pas lire la propriété 'setdata' de NULL Error
- Buctf passing Diary - - [Netting Cup 2020 Qinglong Group] areuserialz
- Notes d'apprentissage du système intégré
- Cartesi mars 2022 Review
- Double pointeur quotidien leetcode - 7
Devinez que vous aimez
Ji Yuan Community ai Weekly # 90: Ma Yi pense que l'intelligence ne peut pas dépendre d'une grande puissance de calcul; Hugging face blog pour découvrir les détails de la formation bloom; Annonce du prix ICML pour la meilleure thèse
Typescript
Outils open source Introduction aux outils SAP ui5
Guide du tutoriel Lark
Sécurité du réseau - pénétration à l'aide d'une vulnérabilité de sécurité d'accès physique Evil Maid
Sécurité du réseau - pénétration et renforcement à l'aide d'une vulnérabilité locale Ubuntu
Rédaction de la classe d'outils jwt
Boom 3D Serial Number Licensing superbes Sound Enhancement and player Tools
Day1 Running SUMM of 1D Array / find pivot index / queue with two Stacks
Introduction de l'API commune de programmation de socket et mise en œuvre de socket, select, Poll et epoll
Recommandé au hasard
- Approfondir la file d'attente des conteneurs
- Méthode de rappel d'initialisation pour Bean et méthode de rappel pour libérer les ressources
- Enregistrer les données crawler dans la base de données MySQL
- Distribution des données via SQL
- Comment renouveler automatiquement les serrures distribuées redis (solution classique)
- Hongke Dynamics | cippe2022 est sur le point de se tenir, l'inscription est en cours
- Classe interne anonyme de kotlin (objet: XXXX)
- Interview raid: 6 grandes différences entre truncate, delete et Drop
- Ubuntu installe docker et les commandes de base de docker installent MySQL
- Leetcode - - Stack and queue articles
- Déploiement du cluster etcd
- Dix problèmes dans la famille de protocoles TCP / IP
- 【 stm32 learning】 (21) stm32 Implementing Stepper Motor
- Dessiner le tableau [grafana] avec les variables des critères de requête
- Reconnaître les interfaces
- LabVIEW: créer un VI
- Cadre de développement de l'interface devextreme Gantt Control - Exporter PDF, trier les tâches
- Exportation et importation de bases de données et de tableaux de données en ligne de commande MySQL
- Easyeeagle, une plate - forme intelligente d'exploitation et de maintenance avec plusieurs plateformes de base de données massives
- Vous souvenez - vous de offsetwidth, clientwidth, width, scrollwidth, clientx, screenx, offsetx, pagex dans JS?
- 【 Azure Event center】 Azure Event hub New Function attempt - GEO Disaster Recovery
- Quels sont les facteurs qui influent sur la prestation continue?
- 【 Tutoriel de démarrage rapide 7】 utilisation et introduction de l'ordinateur hôte de la station au sol de l'UAV en formation de coquille folle · Open Source
- Détails de la configuration redis
- Docker installe MySQL, redis
- Le circuit de limitation d'amplitude et le circuit de serrage utilisent la conductivité unidirectionnelle de la diode
- [carte des connaissances] cql et py2neo notes d'apprentissage
- C apprentissage des langues
- Application combinée de la ligne de transfert de colonne et de l'ensemble de données dans le scénario d'affaires
- Configuration SSL MySQL 5.6 / 5.7
- [apprentissage profond] fonction de perte (erreur absolue moyenne, erreur carrée moyenne, perte de lissage, entropie croisée, entropie croisée pondérée, perte de dé, focalloss)
- Optimisation de précision * stratégie d'optimisation 1: Réseau + optimiseur Sam
- Détails du Protocole Axi
- JS - - date Object & Ternary expression
- Leetcode - 494. Objectifs et
- L'interface utilisateur 3D ou le modèle dans l'unit é fait toujours face à la caméra et tourne avec l'angle de vue de la caméra 丨 l'angle de vue suit 丨 l'angle de vue fixe
- Discussion préliminaire sur JVM
- Déploiement de l'environnement appium pour les tests mobiles [à poursuivre]
- À propos du montage de fond, de la gestion des processus
- Lire la lecture efficace - l'auto - investissement le plus rentable