Je souhaite pouvoir comparer 2 images (même format) et effectuer une comparaison de niveau de bits sur ces images. 1) créer des structures pour les en-têtes.2) ouvrir les fichiers et lire le contenu à partir du décalage de données d'image à partir du marqueur SOI.3) Stockez les valeurs respectives dans un tableau 3d ou un tableau vectoriel.4) Faire une comparaison sage des éléments renvoie un résultat. J'ai réussi à le faire pour un bmp en utilisant fread() et j'ai utilisé un tableau 3d comme un conteneur avec des méthodes qui peuvent allouer et libérer de la mémoire (mais les bmp sont des images non compressées). D'une certaine manière ce processus semble beaucoup plus difficile pour les jpeg et les tiffs. Même après avoir compris le format d'en-tête de ces 2 formats, mon code dit qu'il ne peut pas lire la couleur à l'élément [45] [24] .J'ai regardé plusieurs autres options comme libjpeg et CImg mais je voudrais obtenir un point de vue avant de sauter dans une nouvelle bibliothèque.jpeg et tiff Extraction de valeur de pixel
Mon code pour bmp est la suivante: ... snip ...
unsigned char*** create3dArray(FILE **fptr1,int height,int width,int depth)
{
unsigned char*** databuff = new unsigned char **[height];
// Allocate an array for each element of the first array
for(int x = 0; x < height; ++x)
{
databuff[x] = new unsigned char *[width];
// Allocate an array of integers for each element of this array
for(int y = 0; y < width; ++y)
{
databuff[x][y] = new unsigned char[depth];
// Specify an initial value (if desired)
for(int z = 0; z < depth; ++z)
{
databuff[x][y][z] = -1;
}
}
}
if ((sizeof(fheader) != 14) || (sizeof(iheader) != 40))
{
printf("Header structs are not properly packed\n");
return 0;
}
if (fread(&fheader, sizeof(fheader), 1, *fptr1) != 1)
{
printf("Couldn't read fheader.\n");
return 0;
}
if (fread(&iheader, sizeof(iheader), 1, *fptr1) != 1)
{
printf("Couldn't read iheader.\n");
return 0;
}
// uncomment to get an idea of what the headers look like.
if ((iheader.height != height) || (iheader.width != width) || (iheader.bits != 24))
{
printf("This only works for 512x512 24-color bitmaps\n");
return 0;
}
if (fheader.offset != 54) {
printf("This only works if the offset is equal to 54\n");
return 0;
}
for (int i = 0; i < iheader.height; i++) {
for (int j = 0; j < iheader.width; j++) {
if (fread(&databuff[i][j][0], 3, 1, *fptr1) != 1){
printf("Couldn't read colors for element [%d][%d]\n", i, j);
return 0;
}
}
}
return databuff;
}
template <typename Tx>
void destroy3dArray(Tx*** myArray)
{
delete[] **myArray;
delete[] *myArray;
delete[] myArray;
}
int main()
{
FILE *fptr1,*fptr2; // two file pointers one for each file.
int count=0;
float total_bits=0;
float ber=0; //variable for bit error rate
int width,height,depth;
cout<<"Please enter height of the image "<<endl;
cin>>height;
cout<<"Please enter width of the image "<<endl;
cin>>width;
cout<<"Please enter depth of the image. The max depth can be 3 for RGB values"<<endl;
cin>>depth;
char *filename = "lena512.bmp";
char *filename2 = "lena512_2.bmp";
//std::string trueBinaryDataInString[512][512][3];
if ((fptr1 = fopen(filename, "r")) == NULL) {
printf("Coulsn't open file %s for reading.\n", filename);
return 1;
}
unsigned char*** trueArray = create3dArray(&fptr1,height,width,depth);
for(int i=0;i<height;i++)
{
//std::cout << "Row " << i << std::endl;
for(int j=0;j<width;j++)
{
for(int k=0;k<depth;k++)
{
total_bits += ToBinary(trueArray[i][j][k]).length();
}
//std::cout<<endl;
}
//std::cout<<endl;
}
std::cout << total_bits<<endl;
//createAnddestroy3dArray<unsigned char> MyArray;
if ((fptr2 = fopen(filename2, "r")) == NULL) {
printf("Coulsn't open file %s for reading.\n", filename2);
return 1;
}
unsigned char*** trueArray2 = create3dArray(&fptr2,height,width,depth);
/*for(int i=0;i<512;i++)
{
std::cout << "Row " << i << std::endl;
for(int j=0;j<512;j++)
{
for(int k=0;k<3;k++)
{
std::cout<<" "<<ToBinary(trueArray2[i][j][k]);
}
std::cout<<endl;
}
std::cout<<endl;
}
*/
/******** BIT Error Rate Calculation ******/
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
for(int k=0;k<depth;k++)
{
if(ToBinary(trueArray[i][j][k])!= ToBinary(trueArray2[i][j][k]))
{
std::cout<<ToBinary(trueArray[i][j][k])<< " " <<ToBinary(trueArray2[i] [j][k])<<endl;
count++;
}
else
continue;
}
}
}
ber = (count/total_bits)*100;
std::cout<<"Bit Error Rate (BER) = "<<ber<<endl;
destroy3dArray<unsigned char>(trueArray); //Deallocating memory for array 1
destroy3dArray<unsigned char>(trueArray2); //Deallocating memory for array 2
return 0;
}
Donc, je devrais d'abord convertir ces formats de fichiers en bmp. Comme pour charger un fichier jpg d'abord, puis enregistrez-le en tant que fichier bmp, puis utilisez ces fichiers. Si oui, alors le changement d'état affectera-t-il les informations d'en-tête? – user1227372
Pas nécessairement pour réenregistrer en .BMP, mais c'est aussi possible. Les bibliothèques mentionnées sur les réponses vous permettent de charger et décompresser en mémoire, sans sauvegarder dans le fichier intermédiaire. Les bibliothèques vous permettent également d'accéder aux métadonnées du fichier d'origine, au cas où vous en auriez besoin. –