L'information mutuelle et l'entropie conjointe de deux images - MATLAB
J'ai deux images en noir et blanc et j'ai besoin de calculer l'information mutuelle.
Image 1 = X
Image 2 = Y
Je sais que l'information mutuelle peut être définie comme:
MI = entropy(X) + entropy(Y) - JointEntropy(X,Y)
MATLAB a déjà intégré des fonctions pour calculer l'entropie, mais pas pour calculer l'entropie conjointe. Je suppose que la vraie question est: Comment dois-je calculer l'entropie conjointe de deux images?
Voici un exemple des images, je voudrais trouver l'articulation de l'entropie de:
X =
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
Y =
0 0 0 0 0 0
0 0 0.38 0.82 0.38 0.04
0 0 0.32 0.82 0.68 0.17
0 0 0.04 0.14 0.11 0
0 0 0 0 0 0
- Si votre image intensités sont dans la gamme de
[0,1]
, alors vous pouvez toujours utiliser le code que j'ai écrit ci-dessous, mais vous devez vous assurer que les intensités sont des nombres entiers. Si vous avez des images 8 bits, utilisezim2uint8
avant de passer par ce que j'ai fait. - Aussi, si votre image est purement binaire, alors ne pas convertir à l'aide de
im2uint8
que ce serait un gaspillage de l'espace. Vous pouvez utiliser le code comme il est. La laisse comme un histogramme avec 4 conjointe des bacs au lieu d'avoir256 x 256
. - Merci beaucoup pour votre aide. J'ai fini par en multipliant mon image par 100, puis arrondir le nombre + 1 ->Im1 = round(100*Im0+1) de Cette façon, j'ai corrigé toutes les erreurs 1) le code veut entiers 2) il veut que des valeurs positives. 😀
- Si votre image est une image 8 bits, je ne recommande pas de vous le faire en raison de la perte de bin comte. Je voudrais encore convertir votre image à l'aide de
im2uint8
. Cela vous permettra de transformer votre image à[0,255]
. Aussi, si vous regardez comment MATLAB met en œuvre laentropy
commande, ils utilisent égalementim2uint8
ainsi. Vous devez être cohérent avec la façon dont de nombreux bacs que vous êtes en utilisant pour les deuxentropy
et ce que nous en avons parlé avec joint d'entropie.
Vous devez vous connecter pour publier un commentaire.
Pour calculer l'entropie conjointe, vous devez calculer l'histogramme conjoint entre les deux images. L'articulation de l'histogramme est essentiellement la même que la normale histogramme 1D mais la première dimension journaux intensités pour la première image et la deuxième dimension journaux intensités pour la deuxième image. Ceci est très similaire à ce qui est communément appelé un la co-occurrence de la matrice. Au lieu
(i,j)
dans l'articulation de l'histogramme, il vous indique le nombre de valeurs d'intensité que nous avons rencontrés, qui ont une intensité dei
dans la première image et l'intensitéj
dans la seconde image.Ce qui est important, c'est que ce dernier enregistre combien de fois nous avons vu cette paire d'intensités à la même emplacements correspondants. Par exemple, si nous avons un histogramme conjoint comte de
(7,3) = 2
, cela signifie que lorsque nous étions en analysant à la fois les images, quand nous avons rencontré l'intensité de7
, au même emplacement correspondant dans la deuxième image, nous avons rencontré l'intensité de3
pour un total de2
fois.La construction d'un histogramme conjoint est très simple à faire.
256 x 256
de la matrice (en supposant que votre image est non signé de 8 bits entier) et les initialiser à tous les zéros. Aussi, vous devez vous assurer que vos deux images sont de la même taille (largeur et hauteur).1
.On serait tenté de le faire avec
for
boucles, mais comme il est communément connu,for
boucles sont notoirement lent et doit être évitée si possible. Cependant, vous pouvez facilement le faire en MATLAB de la façon suivante sans boucles. Supposons queim1
etim2
sont les première et deuxième images que vous souhaitez comparer. Ce que nous pouvons faire est de convertirim1
etim2
en vecteurs. Nous pouvons ensuite utiliseraccumarray
pour nous aider à calculer l'histogramme conjoint.accumarray
est l'une des plus puissantes fonctions de MATLAB. Vous pouvez la considérer comme une miniature paradigme MapReduce. Il suffit de mettre, chaque entrée de données a une clé et une valeur associée. L'objectif deaccumarray
est-à-bin de toutes les valeurs qui appartiennent à la même clé et faire une opération sur l'ensemble de ces valeurs. Dans notre cas, la "clé" pourrait être l'intensité des valeurs, et les valeurs sont eux-mêmes la valeur de1
pour chaque valeur d'intensité. Nous voulons ajouter toutes les valeurs de1
que la carte à la poubelle, ce qui est exactement comment nous faisons pour calculer un histogramme. Le comportement par défaut pouraccumarray
est d'ajouter l'ensemble de ces valeurs. Plus précisément, la sortie deaccumarray
serait un tableau où chaque position calcule la somme de toutes les valeurs qui ont cartographié à cette clé. Par exemple, la première position est la somme de toutes les valeurs qui ont cartographié à la clé de 1, la deuxième position est la somme de toutes les valeurs qui ont cartographié à la clé de 2 et ainsi de suite.Cependant, pour le joint de l'histogramme, vous voulez comprendre les valeurs de la carte à la même intensité paire de
(i,j)
, et donc les touches ici serait une paire de coordonnées 2D. En tant que tel, toutes les intensités qui ont une intensité dei
dans la première image etj
dans la seconde image dans la même localisation spatiale partagé entre les deux images allez sur la même touche. Par conséquent, dans le 2D cas, la sortie deaccumarray
serait une matrice 2D où chaque élément(i,j)
contient la somme de toutes les valeurs qui ont cartographié à clé(i,j)
, semblable à la 1D cas qui a été mentionné précédemment ce qui est exactement ce que nous sommes après.En d'autres termes:
Avec
accumarray
, la première entrée sont les clés et la seconde entrée sont les valeurs. Une note avecaccumarray
est que si chaque touche a la même valeur, vous pouvez tout simplement créer une constante à la deuxième entrée, qui est ce que j'ai fait et c'est1
. En général, c'est un tableau avec le même nombre de lignes que la première entrée. Aussi, prenez note de la première deux lignes. Il y aura inévitablement une intensité de0
à votre image, mais parce que MATLAB commence indexation à1
, nous avons besoin de compenser à la fois les tableaux par1
.Maintenant que nous avons l'articulation de l'histogramme, c'est vraiment simple à calculer l'entropie conjointe. Il est similaire à l'entropie en 1D, sauf que maintenant nous avons juste la sommation sur l'ensemble de la probabilité conjointe de la matrice. Gardez à l'esprit qu'il sera très probable que votre conjoint histogramme aura beaucoup de
0
entrées. Nous devons nous assurer que nous ignorer ceux-ci ou de lalog2
opération ne sera pas défini. Débarrassons-nous de tout zéro inscriptions:Prendre avis que j'ai cherché l'articulation de l'histogramme au lieu de la probabilité conjointe de la matrice. C'est parce que l'articulation de l'histogramme est constitué de nombres entiers, tandis que la probabilité conjointe de la matrice sera comprise entre
0
et1
. En raison de la division, je veux éviter de comparer toutes les entrées dans cette matrice avec0
en raison numérique d'arrondi et de l'instabilité. La ci-dessus sera également convertir nos probabilité conjointe de la matrice dans un empilées les 1D vecteur, ce qui est bien.En tant que tel, l'articulation de l'entropie peut être calculé comme:
Si ma compréhension du calcul de l'entropie pour une image de MATLAB est correcte, elle doit calculer l'histogramme /distribution de probabilité sur les
256
bacs, de sorte que vous pouvez certainement utiliser cette fonction, ici, avec la commune d'entropie qui vient d'être calculée.Si nous avons des données en virgule flottante à la place?
Jusqu'à présent, nous avons supposé que les images que vous avez traité avec des niveaux qui sont une valeur entière. Que faire si nous avons de données à virgule flottante?
accumarray
suppose que vous essayez d'index dans le tableau de sortie à l'aide de nombres entiers, mais nous pouvons certainement accomplir ce que nous voulons avec cette petite bosse sur la route. Ce que vous voulez faire est de simplement attribuer à chaque valeur en virgule flottante dans les deux images ont une ID unique. Vous serait donc utiliseraccumarray
avec ces Id à la place. Pour faciliter cette ID de l'attribution, l'utilisationunique
- plus précisément, la troisième sortie de la fonction. Vous devez prendre chacune des images, de les mettre enunique
et à faire de ces indices à être entrée dansaccumarray
. En d'autres termes, faire ceci à la place:Noter qu'avec
indrow
etindcol
, nous sommes assigner directement la troisième sortie deunique
à ces variables, puis à l'aide de la commune même de l'entropie de code que nous avons calculé plus haut. En outre, nous n'avons pas à compenser les variables par 1 comme nous l'avons fait précédemment, carunique
va affecter des codes à partir de 1.De côté
Vous pouvez réellement calculer les histogrammes ou des distributions de probabilité pour chaque image individuellement à l'aide de la probabilité conjointe de la matrice. Si vous vouliez calculer les histogrammes /distributions de probabilité pour la première image, il vous suffit d'accumuler toutes les colonnes pour chaque ligne. De le faire pour la deuxième image, il vous suffit d'accumuler toutes les lignes de chaque colonne. En tant que tel, vous pouvez le faire:
Après, vous pouvez calculer l'entropie de la fois par vous-même. Pour vérifier, assurez-vous de mettre ces deux en Pdf, puis calculer l'entropie à l'aide de l'équation standard (comme ci-dessus).
Comment puis-je enfin de calcul de l'Information Mutuelle?
Enfin de calcul de l'Information Mutuelle, vous allez avoir besoin de l'entropie des deux images. Vous pouvez utiliser MATLAB intégré dans
entropie
fonction, mais cela suppose qu'il existe 256 niveaux uniques. Vous voulez probablement pour appliquer ce pour le cas où il y aN
niveaux distincts au lieu de 256, et vous pouvez donc utiliser ce que nous avons fait ci-dessus avec le conjoint de l'histogramme, lors du calcul de la histogrammes pour chaque image dans le côté le code ci-dessus, puis calcul de l'entropie pour chaque image. Il vous suffit de répéter l'entropie de calcul qui a été utilisé conjointement, mais de l'appliquer à chaque image individuellement:Espérons que cette aide!
for
boucles.accumarray
.im1 = ones(10,10); im2 = ones(10,10);
log2
de que est de 0.im1 = rand(10,10); im2 = rand(10,10);
elle renvoie toujours6.6439
et va de même avec lesim1 = rand(10,10); im2 = im1;
.edges = -1:0.01:1; im1b = discretize(im1,edges); im2b = discretize(im2,edges);
discretize
afin de les adapter pour les anciennes versions de MATLAB. Je vais mettre à jour quand je suis en mesure de. Merci pour l'entrée!