-1
votes

Image.fromarray () fait tous les éléments du mod de la matrice de 256

J'écris un script pour chiffrer et déchiffrer une image à Python3 en utilisant Pil. Ici, je convertissons l'image en une matrice numpue, puis multipliez tous les éléments du tableau avec 10. Maintenant, j'ai remarqué que la fonction par défaut dans PilTarray () convertissait chaque élément du tableau au mod de 256 si son plus grand que le 255, alors quand j'essaie de récupérer la valeur initiale de la matrice, je ne reçois pas l'original. Par exemple, si la valeur d'origine est de 40 ans, son 10 fois est de 400 de sorte que le FaraRray () le rend comme 400 mod 256, qui donnera 144. Maintenant, si j'ajoute 256 à 144, je aurai 400, puis divisé par 10 donnez-moi 40. Mais si la valeur est de 54, il est que 540 et 540 mod 256 est 28. Maintenant, pour récupérer la valeur d'origine, j'ai besoin d'ajouter 256 deux fois qui me donnera 540. 540 N'est pas le seul chiffre qui sera Donnez-moi 28 quand je vais le moder avec 256. Donc je ne saurai jamais quand ajouter 256 une fois et quand deux fois ou plus. Y a-t-il un moyen de le faire arrêter de remplacer tous les éléments de la matrice avec son mod de 256? xxx

une partie de la matrice d'origine avant de multiplier avec 10: [41 42 45 ... 47 41 33]

[41 43 45 ... 44 38 30]

[41 42 46 ... 41 36 30]

[43 43 44 ... 56 56 55]

[45 44 45 ... 55 55 54]

[46 46 46 ... 53 54 54 ]

une partie de la matrice après multiplication avec 10: [[154 164 194 ... 214 154 74]

[154 174 194 ... 184 124 44]

[154 164 204 ... 154 104 44]

[174 174 184 ... 48 48 38]

[194 184 194 ... 38 38 28]

[204 204 204 ... 18 28 28]

une partie de la matrice attendue après la division de 10: [41 42 45 ... 47 41 33]

[41 43 45 ... 44 38 30]

[41 42 46 ... 41 36 30]

[43 43 44 ... 56 56 55]

[45 44 45 ... 55 55 54]

[46 46 46 ... 53 54 54 ]

une partie de la sortie Le script fournit: [[[[4 41 45 ... 48 40 33]

[41 43 44 ... 44 37 31]

[41 41 48 ... 41 35 30]

[44 42 43 ... 30 30 29]

[44 42 45 ... 29 29 29 ]

[45 47 44 ... 28 28 28]]


7 commentaires

Partagez votre code PLZ


Fait, toute aide sera grandement appréciée.


Pouvez-vous partager attendu et votre résultat réel?


Fini. J'espère que cela aidera.


Qu'attendez-vous devrait-il accéder à une valeur> 255 enregistrée dans un fichier JPEG qui ne supporte que les valeurs de la gamme [0,255]?


Je sais que et je veux juste que la valeur de Greyscale de l'image puis je appliquerai RSA Algo ou tout autre algo, mais de faire cela, je dois avoir une matrice qui ne créera pas automatiquement le mod des éléments.


Le codage RSA changera (augmenter beaucoup, probablement) la taille de vos données. Vous pouvez le stocker de toute façon octet par octet, de sorte que le problème que vous rencontrez ici ne surgisse même pas. Étant donné que l'image aura une taille différente, n'oubliez pas de stocker la taille d'image d'origine ni d'autres métadonnées nécessaires pour restaurer l'image.


3 Réponses :


3
votes

Il y a plusieurs problèmes avec ce que vous essayez de faire ici.

Les images de PIL sont soit 8 bits par canal ou 16 bits par canal (au meilleur de mes connaissances). Lorsque vous chargez un JPEG, il est chargé sous forme de 8 bits par canal, de sorte que le type de données sous-jacent est un entier 8 bits non signé, c'est-à-dire 0..255. Opérations qui débordiez ou déborderaient cette gamme d'emballage, qui ressemble au comportement du module que vous voyez.

Vous pouvez convertir l'image PIL 8 bits en une matrice numpie à virgule flottante avec np.array (img) .astype ('float32') puis normaliser ceci à 0..1 en divisant avec 255.

À ce stade, vous avez des chiffres de points flottants non quantifiés que vous pouvez librement mangmary, mais vous le souhaitez.

Cependant, vous devez toujours enregistrer l'image résultante, à laquelle vous avez à nouveau un problème de format. Je crois que les tiffs et certains formats d'image HDR prennent en charge les données de points flottants, mais si vous voulez quelque chose qui est largement lisible, vous iriez probablement pour PNG ou JPEG.

Pour un boîtier d'utilisation de cryptage, les JPEG ne sont pas un bon choix, car ils sont toujours une perte intrinsèquement, et vous le souhaitez, plus susceptibles de ne pas obtenir les mêmes données.

PNGS peut être de 8 ou 16 bits par canal, mais vous auriez toujours le problème de devoir compresser une "plage dynamique" fondamentalement infinie de pixels (disons que vous multipliez tout de mille!) dans 0? ..255 ou 0..65535.

Un moyen évident de le faire est de trouver la valeur maximale de l'image ( np.max (...) ), divise tout par celui-ci (alors maintenant vous êtes de retour à 0. .1), puis multipliez la valeur maximale du format de données d'image ... SO avec un "chiffre" de multiplication simple, comme vous l'aviez décrit, vous obtiendrez essentiellement la même image.

Un autre moyen serait de clipser la plage infinie aux valeurs autorisées, c'est-à-dire que tout est inférieur à zéro est zéro, tout ce qui précède, c'est, disons, 65535. Ce serait une opération de perte, et vous n'aviez aucun moyen de Obtenir les valeurs inclinées.


0 commentaires

2
votes

Tout d'abord, PIL ne prend en charge que 8 bits par canal images - bien que oreiller (la fourche PIL) prend en charge de nombreux autres formats y compris des profondeurs de bits plus élevées. Le format JPEG est défini comme seulement 8 bits par canal.

appeler Image.open () code> sur un JPEG in Pil va donc renvoyer un tableau 8 bits, de sorte que toutes les opérations sur des pixels individuels seront effectuées équivalentes à uint8_t code> arithmétique dans la représentation du support. Étant donné que la valeur maximale d'un uint8_t code> est de 256, tout votre arithmétique est nécessairement modulo 256. p>

Si vous souhaitez éviter cela, vous devez convertir la représentation en un Profondeur de bits plus élevée, tels que 16 bpp ou 32bpp. Vous pouvez le faire avec le code NUMPY, tel que: P>

img16 = np.array(img, dtype=np.uint16)
# or
img32 = np.array(img, dtype=np.uint32)


2 commentaires

Oui, réellement mon projet est de chiffrer une image à l'aide de RSA Algo. J'essayais juste cela afin que je puisse écrire efficacement le projet réel, puis j'ai couru dans ce problème.


Le tableau de ces types ne peut pas être enregistré directement dans JPEG. Vous pouvez améliorer votre réponse en fournissant le code pour stocker ces données dans une image RVB et récupérer les données.



1
votes

Comme aucune des réponses ne m'a aidé que beaucoup et que j'ai résolu le problème, je voudrais donner une réponse en espérant qu'un jour, cela aidera quelqu'un. Ici, les clés sont (3, 25777) et (16971.25777). Le code de travail est le suivant:

from PIL import Image
import numpy as np 

#encryption
img1 = (Image.open('image.jpeg').convert('L')) 
img1.show()

img = array((Image.open('image.jpeg').convert('L'))) 
img16 = np.array(img, dtype=np.uint32)
a,b = img.shape
print('\n\nOriginal image: ')
print(img16)
print((a,b))
tup = a,b

for i in range (0, tup[0]):
    for j in range (0, tup[1]):
        x = img16[i][j] 
        x = (pow(x,3)%25777)
        img16[i][j] = x
print('\n\nEncrypted image: ')
print(img16)
imgOut = Image.fromarray(img16)
imgOut.show()

#decryption

img3_16 = img16
img3_16 = np.array(img, dtype=np.uint32)
print('\n\nEncrypted image: ')
print(img3_16)
a1,b1 = img3_16.shape
print((a1,b1))
tup1 = a1,b1

for i1 in range (0, tup1[0]):
     for j1 in range (0, tup1[1]):
         x1 = img3_16[i1][j1] 
         x1 = (pow(x,16971)%25777)  
         img3_16[i][j] = x1
print('\n\nDecrypted image: ')
print(img3_16)
imgOut1 = Image.fromarray(img3_16)y
imgOut1.show()


3 commentaires

Avez-vous tenté de sauvegarder l'image "chiffrée" dans un fichier et de le charger à nouveau dans un fichier?


Non mais je pense que .bpm ne supportera pas ce type de données


Je dirais que c'est un rôle assez intégral à essayer également.